Tag: multithreading

如何从另一个类更新Windows窗体GUI?

如何从创建GUI而不是创建线程的另一个类更新win表单控件(例如标签,进度条)? (例如,Program.cs的事件处理程序) 我发现了几篇关于使用Invoke()方法从另一个线程更新GUI的post,但到目前为止我发现的只有在代码与表单编写在同一个类中时才有效 http://www.yoda.arachsys.com/csharp/threads/winforms.shtml

为什么每个Dispatcher.BeginInvoke回调都有一个唯一的同步上下文?

我刚刚注意到,使用.NET 4.5,每个Dispatcher.BeginInvoke / InvokeAsync回调都在其自己非常独特的同步上下文( DispatcherSynchronizationContext一个实例)上执行。 这种变化背后的原因是什么? 以下简单的WPF应用程序说明了这一点: using System; using System.Diagnostics; using System.Threading; using System.Windows; using System.Windows.Threading; namespace WpfApplication { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Action test = null; var i = 0; test = () => { var sc = SynchronizationContext.Current; Dispatcher.CurrentDispatcher.InvokeAsync(() => { Debug.Print(“same context #” + […]

暂停/恢复与AutoResetEvent相关的线程

在这段代码中,我想使用AutoResetEvent和bool变量暂停/恢复一个线程。 如果阻塞== true,是否可以每次暂停不进行测试(在for循环中工作())? 测试“阻塞”变量也需要锁定,我认为这是耗时的。 class MyClass { AutoResetEvent wait_handle = new AutoResetEvent(); bool blocked = false; void Start() { Thread thread = new Thread(Work); thread.Start(); } void Pause() { blocked = true; } void Resume() { blocked = false; wait_handle.Set(); } private void Work() { for(int i = 0; i < 1000000; i++) { if(blocked) […]

使用Task.Run调用异步方法似乎错了?

我最近遇到了这个由我们为我们工作的承包商编写的代码。 它要么是非常聪明或愚蠢(我认为后者,但我想要第二个意见)。 我不是在await async速度。 基本上它的工作方式如下: public bool Send(TemplatedMessageDto message) { return Task.Run(() => SendAsync(message)) .GetAwaiter() .GetResult(); } public async Task SendAsync(TemplatedMessageDto message) { //code doing stuff var results = await _externalresource.DothingsExternally(); //code doing stuff } 现在据我所知,第一个Task.Run()是没有意义且效率低下的? 应该是: public bool Send(TemplatedMessageDto message) { return SendAsync(message)) .GetAwaiter() .GetResult(); } public async Task SendAsync(TemplatedMessageDto message) { //code doing […]

BackgroundWorker OnWorkCompleted抛出跨线程exception

我有一个简单的UserControl用于数据库分页,它使用控制器来执行实际的DAL调用。 我使用BackgroundWorker来执行繁重的工作,并在OnWorkCompleted事件上重新启用一些按钮,更改TextBox.Text属性并为父窗体引发事件。 表单A保存我的UserControl。 当我点击打开表单B的某个按钮时,即使我没有做任何“那里”并且只是关闭它,并尝试从我的数据库引入下一页, OnWorkCompleted会在工作线程上调用(而不是我的主线程),并抛出一个跨线程exception。 目前我在那里的处理程序中添加了对InvokeRequired的检查,但是不是要在主线程上调用OnWorkCompleted的全部内容吗? 为什么不按预期工作? 编辑: 我设法将问题缩小到arcgis和BackgroundWorker 。 我有以下解决方案,它向arcmap添加一个命令,打开一个带有两个按钮的简单Form1 。 第一个按钮运行一个hibernate500毫秒的BackgroundWorker并更新计数器。 在RunWorkerCompleted方法中,它检查InvokeRequired ,并更新标题以显示方法最初在主线程或工作线程内运行。 第二个按钮只打开Form2 ,它什么都不包含。 首先,所有对RunWorkerCompletedare的调用都是在主线程内完成的(正如预期的那样 – 这就是RunWorkerComplete方法的最后一点,至少我从BackgroundWorker上的MSDN中了解到的) 打开和关闭Form2 ,始终在工作线程上调用RunWorkerCompleted 。 我想补充一点,我可以将此解决方案保留原样(在RunWorkerCompleted方法中检查InvokeRequired ),但我想了解为什么它会违背我的期望。 在我的“真实”代码中,我想知道在主线程上调用RunWorkerCompleted方法。 我设法在form.Show(); 我的BackgroundTesterBtn命令 – 如果我使用ShowDialog() ,我没有问题( RunWorkerCompleted总是在主线程上运行)。 我需要在我的ArcMap项目中使用Show() ,这样用户就不会绑定到表单了。 我还尝试在正常的WinForms项目上重现该错误。 我添加了一个简单的项目,只打开没有ArcMap的第一个表单,但在这种情况下我无法重现该错误 – RunWorkerCompleted在主线程上运行,无论我在打开Form2之前和之后使用Show()或ShowDialog() 。 我尝试在Form1之前添加第三个表单作为主表单,但它没有改变结果。 这是我的简单sln(VS2005sp1) – 它需要 ESRI.ArcGIS.ADF(9.2.4.1420) ESRI.ArcGIS.ArcMapUI(9.2.3.1380) ESRI.ArcGIS.SystemUI(9.2.3.1380)

WinFormmultithreading。 是否使用backgroundWorker?

我有一个简单的应用程序,它触发了一系列数据密集型任务。 我对WinForms不是很有经验,我想知道在不锁定界面的情况下最好的方法。 可以重复使用backgroundWorker,还是有其他方法可以做到这一点? 谢谢

我需要在ManualResetEvent上调用Close()吗?

我一直在阅读.NET Threading,并正在研究一些使用ManualResetEvent的代码。 我在互联网上找到了很多代码示例。 但是,在阅读WaitHandle的文档时,我看到以下内容: WaitHandle实现了Dispose模式。 请参阅实现Finalize和Dispose以清理非托管资源。 没有任何样本似乎在他们创建的ManualResetEvent对象上调用.Close(), 甚至是来自pfxteam博客的好的Recursion and Concurrency文章 ( 编辑 – 这有一个我错过的使用块)。 这只是示例疏忽,还是不需要? 我很好奇,因为WaitHandle“封装了特定于操作系统的对象”,因此很容易出现资源泄漏。

多个任务变慢

代码: static void DoIt(string name) { Console.WriteLine(“Hello {0} | {1}”, name, Thread.CurrentThread.ManagedThreadID); Thread.Sleep(5000); Console.WriteLine(“Bye {0} | {1}”, name, Thread.CurrentThread.ManagedThreadID); } static void Main() { Task.Factory.StartNew(() => DoIt(“One”)); Task.Factory.StartNew(() => DoIt(“Two”)); Task.Factory.StartNew(() => DoIt(“Three”)); Task.Factory.StartNew(() => DoIt(“Four”)); Task.Factory.StartNew(() => DoIt(“Five”)); Task.Factory.StartNew(() => DoIt(“Six”)); Task.Factory.StartNew(() => DoIt(“Seven”)); Task.Factory.StartNew(() => DoIt(“Eight”)); Task.Factory.StartNew(() => DoIt(“Nine”)); Task.Factory.StartNew(() => DoIt(“Ten”)); Console.ReadKey(); […]

在.NET安全实践中使用Thread.Abort()并处理ThreadAbortException?

我需要在C#中开发一个multithreading的Azure辅助角色 – 创建多个线程,向它们提供请求,每个请求可能需要一些很长的时间来处理(不是我的代码 – 我将调用COM对象来进行实际工作)。 在角色关闭后,我需要优雅地停止处理。 我怎么做? 看起来如果我只调用Thread.Abort()线程中抛出ThreadAbortException ,线程甚至可以使用try-catch-finally (或using )来清理资源。 这看起来非常可靠。 困扰我的是我的经验主要是C ++,并且不可能在非托管应用程序中优雅地中止线程 – 它将在没有任何进一步处理的情况下停止,这可能会使数据处于不一致状态。 因此,如果我为一个繁忙的线程调用Thread.Abort() ,我是否会有类似的事情。 将Thread.Abort()与ThreadAbortException一起使用是否安全? 如果我这样做,我应该注意什么?

你如何处理挂断电话的线程?

我有一个线程,并尝试建立连接。 在线程中,我打电话给第三方库。 有时,此调用会挂起,永远不会返回。 在UI线程上,我希望能够通过中止线程来取消连接尝试,该线程应该中止对第三方库的挂起调用。 我调用了Thread.Abort,但现在已经读过Thread.Abort仅在控件返回托管代码时才有效。 我观察到这是真的,因为线程永远不会中止,我现在已经坐在Thread.Join上十分钟了。 这个挂线怎么办? 我应该将引用置空并继续吗? 我想尽可能干净 –