Tag: multithreading

关于C#中的lock语句的困惑

这来自MSDN:lock关键字确保一个线程不进入代码的关键部分 ,而另一个线程在关键部分 。 关键部分是否必须与关键部分相同? 或者它是否意味着:lock关键字确保一个线程不会进入由代码对象保护的任何关键部分 ,而另一个线程处于由同一对象保护的任何关键部分 。 ? class Program { static void Main(string[] args) { TestDifferentCriticalSections(); Console.ReadLine(); } private static void TestDifferentCriticalSections() { Test lo = new Test(); Thread t1 = new Thread(() => { lo.MethodA(); }); t1.Start(); Thread t2 = new Thread(() => { lo.MethodB(); }); t2.Start(); } } public class Test { […]

读取由Interlocked在其他线程上更新的int

(这是重复: 如何正确读取Interlocked.Increment’ed int字段?但是,在阅读了答案和评论后,我仍然不确定正确的答案。) 有一些我不拥有的代码,并且无法更改为使用在几个不同线程中增加int计数器(numberOfUpdates)的锁。 所有来电均使用: Interlocked.Increment(ref numberOfUpdates); 我想在我的代码中读取numberOfUpdates。 既然这是一个int,我知道它不会撕裂。 但是,确保我获得最新价值的最佳方法是什么? 看起来我的选择是: int localNumberOfUpdates = Interlocked.CompareExchange(ref numberOfUpdates, 0, 0); 要么 int localNumberOfUpdates = Thread.VolatileRead(numberOfUpdates); 两者都可以工作(无论优化,重新排序,缓存等,都可以提供最新的价值)? 一个优先于另一个? 还有第三种选择更好吗?

寻找自定义SynchronizationContext的示例(unit testing需要)

我需要一个自定义的SynchronizationContext : 拥有一个运行“post”和“发送”代表的单个线程 是按发送顺序发送的 不需要其他方法 我需要这个,所以我可以单独测试一些线程代码,它们将在实际应用程序中与WinForm对话。 在我自己编写之前,我希望有人可以指出我的简单(和小)实现。

DataTable的线程安全性

我曾经读过这个答案ADO.NET DataTable / DataRow Thread Safety ,并且无法理解一些东西。 特别是我无法理解[2]文章。 我需要使用什么样的包装? 谁能举个例子? 另外我无法理解作者的意思是谈论级联锁和完全锁定。 请举例。

在foreach循环中启动一个新线程

我有一个对象列表,我想循环遍历该列表并启动一个新线程,传入当前对象。 我写了一个我认为应该做的事情的例子,但它不起作用。 具体来说,似乎线程在每次迭代时都被覆盖。 这对我来说真的没有意义,因为我每次都在创建一个新的Thread对象。 这是我写的测试代码 class Program { static void Main(string[] args) { TestClass t = new TestClass(); t.ThreadingMethod(); } } class TestClass { public void ThreadingMethod() { var myList = new List { new MyClass(“test1”), new MyClass(“test2”) }; foreach(MyClass myObj in myList) { Thread myThread = new Thread(() => this.MyMethod(myObj)); myThread.Start(); } } public […]

中止对非托管DLL的调用

我有一个非托管DLL,如果输入参数是一个很大的值,它可以运行很长时间,有时这是可取的,但并不总是如此。 我如何在c#中调用此函数以便在需要时可以中止它? 到目前为止,我已经尝试将调用放在一个单独的线程中,但是中断和中止似乎都不会停止进程,该进程在100%CPU运行直到dll完成。 是否可以终止正在运行的DLL代码?

当.NET线程抛出exception时会发生什么?

我们有一个接口IPoller,我们有各种各样的实现。 我们有一个进程将接受一个I​​Poller并在一个单独的线程中启动它。 我正在尝试提出一种通用方法,为任何不自行处理的IPoller提供exception处理。 我最初的想法是创建一个接受IPoller的IPoller实现,并提供一些日志function。 我遇到的问题是如何提供此error handling? 如果我有IPoller.Start()这是Thread的目标,那将发生exception? 或者我可以挂钩的线程本身有什么东西?

如何显示在serialport的DataReceived事件处理程序中读取的数据

我有以下代码,需要从端口读取数据,然后显示在文本框中。 我为此目的使用DataReceived事件处理程序,但不知道如何在文本框中显示此数据。 从各种来源我了解到Invoke方法应该用于此,但不知道如何使用它。 建议请… private void Form1_Load(object sender, EventArgs e) { //SerialPort mySerialPort = new SerialPort(“COM3”); mySerialPort.PortName = “COM3”; mySerialPort.BaudRate = 9600; mySerialPort.Parity = Parity.None; mySerialPort.StopBits = StopBits.One; mySerialPort.DataBits = 8; mySerialPort.Handshake = Handshake.None; mySerialPort.DataReceived += new SerialDataReceivedEventHandler(mySerialPort_DataReceived); mySerialPort.Open(); } private void mySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { SerialPort sp = (SerialPort)sender; string s= sp.ReadExisting(); // […]

C#Downloader:我应该使用Threads,BackgroundWorker还是ThreadPool?

我正在用C#编写一个下载程序并停止了以下问题:我应该使用什么样的方法来并行化我的下载并更新我的GUI? 在我的第一次尝试中,我使用了4个线程,并且在每个线程完成时我开始了另一个:主要问题是我的cpu在每个新线程启动时都是100%。 谷歌搜索,我发现BackgroundWorker和ThreadPool的存在:说我想用我正在下载的每个链接的进度更新我的GUI,什么是最好的解决方案? 1)创建4个不同的BackgroundWorker,附加到每个ProgressChanged事件,委托GUI中的函数来更新进度? 2)使用ThreadPool并将最大和最小线程数设置为相同的值? 如果我选择#2,当队列中没有更multithreading时,是否会停止4个工作线程? 它暂停了吗? 由于我必须下载不同的链接列表(每个链接20个链接)并在完成一个链接时从一个链接移动到另一个链接,ThreadPool是否在每个列表之间启动和停止线程? 如果我想在live上更改工作线程的数量并决定使用ThreadPool,从10个线程更改为6,它是否会抛出exception并停止4个随机线程? 这是让我头疼的唯一部分。 我提前感谢你们每个人的答案。

在哪里放置围栏/内存屏障以保证新的读取/提交写入?

像许多其他人一样,我一直对易失性读/写和围栏感到困惑。 所以现在我想完全理解这些是做什么的。 因此,易失性读取应该(1)表现出获取语义,(2)保证读取的值是新鲜的,即它不是缓存值。 让我们关注(2)。 现在, 我已经读过 ,如果你想执行一个易失性读取,你应该在读取后引入一个获取栅栏(或一个完整的栅栏),如下所示: int local = shared; Thread.MemoryBarrier(); 这究竟是如何阻止读取操作使用以前缓存的值? 根据栅栏的定义(不允许读取/存储在栅栏上方/下方移动),我会在读取之前插入栅栏,防止读取穿过栅栏并及时向后移动(也就是说,缓存)。 如何防止读取被及时向前移动(或后续指令被及时向后移动)保证了易失性(新鲜)读取? 它有什么用? 类似地,我认为易失性写入应该在写入操作之后引入栅栏,从而阻止处理器及时向前移动写入(也就是说,延迟写入)。 我相信这会使处理器刷新对主内存的写入。 但令我惊讶的是, C#实现在写入之前引入了栅栏! [MethodImplAttribute(MethodImplOptions.NoInlining)] // disable optimizations public static void VolatileWrite(ref int address, int value) { MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way. address = value; } 更新 根据这个例子 ,显然是从“坚果壳中的C#4”中取出的, 在写入之后放置的栅栏2应该强制写入立即刷新到主存储器,并且在读取之前放置的栅栏3应该保证一个新的阅读: class […]