Bri*_*ahy 5 vb.net generics multithreading invoke
VB.NET 2010,.NET 4
你好,
我最近读到了使用SynchronizationContext对象来控制某些代码的执行线程.我一直在使用通用子例程来处理(可能)跨线程调用,例如更新使用的UI控件Invoke.我是一名业余爱好者,很难理解任何特定方法的优缺点.我正在寻找一些有关哪种方法可能更可行以及为什么更有用的见解.
更新:此问题的部分原因在于MSDN页面中Control.InvokeRequired的以下语句.
更好的解决方案是使用
SynchronizationContext返回的SynchronizationContext而不是控件来进行跨线程编组.
而且,对于为什么,在我看来,大多数关于SO上此类问题的问题的答案的建议都提出了Invoke这种方法,并没有提到这种方法.
方法1:
Public Sub InvokeControl(Of T As Control)(ByVal Control As T, ByVal Action As Action(Of T))
If Control.InvokeRequired Then
Control.Invoke(New Action(Of T, Action(Of T))(AddressOf InvokeControl), New Object() {Control, Action})
Else
Action(Control)
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
方法2:
Public Sub UIAction(Of T As Control)(ByVal Control As T, ByVal Action As Action(Of Control))
SyncContext.Send(New Threading.SendOrPostCallback(Sub() Action(Control)), Nothing)
End Sub
Run Code Online (Sandbox Code Playgroud)
在我的UI表单的构造函数中定义SyncContext的Threading.SynchronizationContext对象在哪里(我将它存储在模块中......不确定这是否是最佳选择):
Public Sub New()
InitializeComponent()
SyncContext = WindowsFormsSynchronizationContext.Current
End Sub
Run Code Online (Sandbox Code Playgroud)
然后,如果我想Label1在UI表单上更新控件(例如),我会这样做:
InvokeControl(Label1, Sub(x) x.Text = "hello")
Run Code Online (Sandbox Code Playgroud)
要么
UIAction(Label1, Sub(x) x.Text = "hello")
Run Code Online (Sandbox Code Playgroud)
那么,你们都在想什么呢?是一种首选方式还是取决于具体情况?如果你有时间,可以感谢详细!
布莱恩,提前谢谢
好吧,我一直在做一些阅读,由于我没有得到任何答复,我想我应该开始对我自己的问题进行部分回答,其中包含我迄今为止发现的内容:
我发现了一篇有趣的 codeproject 文章,SynchronizationContext讨论了在线程之间(特别是从工作线程到 UI 线程)编组代码的使用。我发现一些有趣的观察:
SynchronizationContext对象是在该线程中创建第一个控件时创建的。在此之前,它没有被定义。SynchronizationContext不是该类的实例SynchronizationContext,而是System.Windows.Forms.WindowsFormsSynchronizationContext从 派生的类的实例SynchronizationContext。正是这个类定义了行为Post/Send允许将代码从一个线程编组到另一个线程。SynchronizationContext传递 UI 线程而不是使用UI 线程的一个好处Invoke是,您不必在逻辑中保留对 UI 表单的引用来调用它。Post方法对于完成指标更新之类的事情似乎很有吸引力,因为它是非阻塞的,但是,正如文章指出的,发布的代码中引发的异常会在 UI 线程中引发。即,发布到 UI 的代码中的错误可能会使 UI 崩溃。 Send没有这个问题。发送时抛出的异常在工作线程中抛出。更新:这是另一篇富有洞察力的文章。在本文中,Kael Rowan 讨论了一种上下文,其中使用SynchronizationContext可能比控件实例的Invoke/BeginInvoke方法更可取。他认为,在编写可重用库时,仅仅出于调用目的而必须维护对库外部控件的引用是不可取的。他为委托提供了代码,确保创建的任何新线程都将共享 UI 线程的SynchronizationContext.
好吧,看来我不会再在这里收到任何评论了。我在这里写的内容是我的无知使我能够得到的最接近的答案。如果有人还有什么要补充的,我肯定会很感激,但我现在要继续了。:/
| 归档时间: |
|
| 查看次数: |
3773 次 |
| 最近记录: |