Tag:

请帮助我使这段代码线程安全

我在使数据加载和过滤线程安全方面遇到了一些问题。 我的控件基类上的以下代码通过BackgroundWorker处理所有数据填充。 这往往会在“this.DataWorker.RunWorkerAsync()”上抛出错误,说明BackgroundWorker正忙。 /// /// Handles the population of the form data. /// /// Whether to pull data back from the WebService. public void Populate(bool reload) { if (!this.DataWorker.IsBusy) { // Disable the filter options IvdSession.Instance.FilterManager.SetEnabledState(this.GetType(), false); // Perform the population this.DataWorker.RunWorkerAsync(reload); } else if (!reload) { // If the data worker is busy and […]

从其他类的线程安全更新WinForm控件

有人可以帮我解决以下问题: MainForm和LWriter有两个类。 以下是来自LWriter的方法,除了写入文件之外,还向RichTextBox控件发送一些更新(通过mainForm.UpdateLog(text))。 一切正常,但是,这个WriteOutput方法也做了一些广泛的处理,在计算过程中冻结了表单。 我认为WriteOutput应该封装在一个单独的线程中。 有人可以帮我解释如何将WriteOutput(LWriter类)放在一个线程中,然后以安全的方式从mainFrom调用mainForm.UpdateLog()吗? 我是线程的新手,因此非常感谢帮助。 public void WriteOutput(string output, Links[] links) { try { using (StreamWriter sw = new StreamWriter(output)) { for (int x= 1; x<links.Length;x++) { … sw.WriteLine( … ); sw.Flush(); } mainForm.UpdateLog(); } } catch(Exception e) { … } }

关于SyncRoot模式的一些说明:使用此模式的正确方法是什么?

我读了一些关于SyncRoot模式的内容,作为避免死锁的一般规则。 阅读几年前的问题(见此链接 ),我想我明白这种模式的一些用法可能是不正确的。 特别是,我专注于这个主题的以下句子: 您会注意到System.Collections中许多集合上的SyncRoot属性。 在回顾中,我认为这个属性是一个错误……请放心,我们不会犯这个错误,因为我们构建这些集合的通用版本。 实际上,例如, List类不实现SyncRoot属性,或者更准确地说它是显式实现的(请参阅此答案 ),因此必须强制转换为ICollection才能使用它。 但是这篇评论认为公开私有SyncRoot字段与锁定它一样糟糕(请参阅此答案 ),这也在本评论中得到证实。 因此,如果我理解正确,当我实现非线程安全的数据结构时,由于它可以在multithreading上下文中使用,我不应该(实际上,我不能)提供SyncRoot属性。 但是我应该让开发人员(将使用此数据结构)的任务是将其与私有SyncRoot对象相关联,如下面的示例代码所示。 public class A { private MyNonThreadSafeDataStructure list; private readonly object list_SyncRoot = new object; public Method1() { lock(list_SyncRoot) { // access to “list” private field } } public Method2() { lock(list_SyncRoot) { // access to “list” private field } } } 总之,我了解同步/锁定的最佳实践应如下所示: […]

Thread.Abort()如何工作?

当无效输入传递给方法或对象即将进入无效状态时,我们通常抛出exception。 让我们考虑以下示例 private void SomeMethod(string value) { if(value == null) throw new ArgumentNullException(“value”); //Method logic goes here } 在上面的例子中,我插入了一个抛出ArgumentNullException的throw语句。 我的问题是运行时如何设置抛出ThreadAbortException 。 显然,在所有方法中都不可能使用throw语句,即使运行时也设法在我们的自定义方法中抛出ThreadAbortException 。 我想知道他们是怎么做到的? 我很想知道幕后发生了什么,我打开一个reflection器来打开Thread.Abort并最终得到这个 [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern void AbortInternal();//Implemented in CLR 然后我用Google搜索并发现了ThreadAbortException如何真正起作用 。 这个链接说运行时通过QueueUserAPC函数发布APC,这就是他们如何做到这一点。 我不知道QueueUserAPC方法我只是试着看看是否可以使用一些代码。 以下代码显示了我的尝试。 [DllImport(“kernel32.dll”)] static extern uint QueueUserAPC(ApcDelegate pfnAPC, IntPtr hThread, UIntPtr dwData); delegate void ApcDelegate(UIntPtr dwParam); Thread t = new […]

在C#实例方法中,’this’可以为null吗?

我有一种情况,很少有对象的队列出列空值。 对Enqueue的唯一调用是在类本身内: m_DeltaQueue.Enqueue(this); 很少,在以下代码中,null会从此队列中出列(静态方法): while (m_DeltaQueue.Count > 0 && index++ < count) if ((m = m_DeltaQueue.Dequeue()) != null) m.ProcessDelta(); else if (nullcount++ < 10) { Core.InvokeBroadcastEvent(AccessLevel.GameMaster, "A Rougue null exception was caught, m_DeltaQueue.Dequeue of a null occurred. Please inform an developer."); Console.WriteLine("m_DeltaQueue.Dequeue of a null occurred: m_DeltaQueue is not null. m_DeltaQueue.count:{0}", m_DeltaQueue.Count); } 这是生成的错误报告: [Jan […]

等待Task.Run(()=> semaphore.WaitOne())有什么问题吗?

标题说明了一切。 await Task.Run(() => semaphore.WaitOne());有什么问题await Task.Run(() => semaphore.WaitOne()); ? System.Threading.Semaphore不是线程仿射的,所以我不认为会有问题。 我知道SemaphoreSlim类是可用的,但我需要进行跨进程同步,而SemaphoreSlim不会这样做。 或者我可以/应该创建自己的自定义类型的WaitHandle吗?

加入线程时是否需要内存屏障?

如果一个线程A生成另一个线程B,其唯一目的是写入变量V然后等待它终止,那么是否需要内存屏障以确保后续读取线程A上的V是新鲜的? 我不确定终止/加入操作中是否有任何隐含的障碍使它们变得多余。 这是一个例子: public static T ExecuteWithCustomStackSize (Func func, int stackSize) { T result = default(T); var thread = new Thread( () => { result = func(); Thread.MemoryBarrier(); // Required? } , stackSize); thread.Start(); thread.Join(); Thread.MemoryBarrier(); // Required? return result; } 是否需要上述代码段中的两个(或更多)障碍?

如何从除创建它之外的线程读取combobox?

我试图从一个线程读取一个combobox.Text而不是它创建的线程,但我收到错误: System.Windows.Forms.dll中发生了未处理的“System.InvalidOperationException”类型exception 附加信息:跨线程操作无效:控制’levelsComboBox’从其创建的线程以外的线程访问。 我之前使用过.Invoke但只是设置属性,我怎样才能用它来读取combobox.Text? 因为.Invoke返回void,我需要一个字符串。 或者没有Invoke有另一种方法吗?

0MQ:如何以线程安全的方式使用ZeroMQ?

我阅读了ZeroMq指南 ,我偶然发现了以下内容: 您不能在线程之间共享ØMQ套接字。 ØMQ套接字不是线程安全的。 从技术上讲,它可以做到这一点,但它需要信号量,锁或互斥量。 这将使您的应用程序变得缓慢而脆弱。 在线程之间共享套接字远程理解的唯一地方是语言绑定,需要像套接字上的垃圾收集那样做魔术。 后来: 切记: 除了创建它们的线程外,不要使用或关闭套接字。 我也明白ZeroMQ Context是线程安全的。 如果一个类在.Net中注册另一个类的事件,则可以从与创建监听器的线程不同的线程调用此事件。 我认为只有两个选项可以从事件处理程序中通过ZeroMQ-Sockets调度: 将eventhandler-invoking-thread同步到创建ZeroMQ- Socket的线程 通过使用线程安全的ZeroMQ- Context为事件处理程序中的线程创建一个新的ZeroMQ- Socket /获取现有的ZeroMQ- Socket 似乎0MQ-Guide不鼓励第一个,我不认为为每个线程创建一个新的ZeroMq-Socket是高性能/可行的方式。 我的问题 : 在事件处理程序中通过0MQ发布消息的正确模式(它的意图是什么)是什么? 此外,该指南的作者在撰写时还考虑了.Net的ZeroMQ-Binding: 在线程之间共享套接字远程理解的唯一地方是语言绑定,需要像套接字上的垃圾收集那样做魔术。 ? 这里有一些示例代码来强调我的问题/问题: public class ExampleClass { public event EventHandler SomethinIsCalledFromAnotherThread; } public class ByteEventArgs : EventArgs { public byte[] BytesToSend; } public class Dispatcher { ZMQ.Context ctx; public […]

由于AcceptSocket,Thread.Abort似乎没有抛出ThreadAbortException

我在下面的线程上调用ChannelServer.ListeningThread.Abort ,但似乎没有任何事情发生。 我想更具体一点,但我想不出更多。 似乎没有抛出ThreadAbortException ,并且无论阻塞侦听器如何都应抛出此exception(它在阻塞接收的线程上完美运行)。 重要编辑 :使用ManualResetEvent.WaitOne而不是AcceptSocket ,正如Lyrik建议进行测试一样,它完美无缺。 为什么AcceptSocket阻止ThreadAbortException ? 链接 :这个论坛主题似乎讨论了同样的问题,虽然我无法解决任何问题: http : //www.tek-tips.com/viewthread.cfm?qid = 319436&page = 413 ChannelServer.ListeningThread = new Thread(new ThreadStart(delegate() { Log.Inform(“Waiting for clients on thread {0}.”, Thread.CurrentThread.ManagedThreadId); while (true) { try { new Thread(new ParameterizedThreadStart(ChannelClientHandler.Initialize)).Start(ChannelServer.Listener.AcceptSocket()); } catch (ThreadAbortException) { Log.Inform(“Aborted client listening thread {0}.”, Thread.CurrentThread.ManagedThreadId); break; } } })); ChannelServer.ListeningThread.Start();