gpt4 book ai didi

VB.NET 两种不同的通用跨线程操作方法;哪个更好?

转载 作者:行者123 更新时间:2023-12-04 20:22:25 25 4
gpt4 key购买 nike

VB.NET 2010、.NET 4

你好,

我最近读到关于使用 SynchronizationContext对象来控制某些代码的执行线程。我一直在使用通用子例程来处理(可能)跨线程调用,例如更新使用 Invoke 的 UI 控件。 .我是一个业余爱好者,很难理解任何特定方法的优缺点。我正在寻找一些关于哪种方法可能更可取以及为什么更可取的见解。

更新:这个问题的部分原因是 MSDN page on Control.InvokeRequired 中的以下陈述.

An even better solution is to use the SynchronizationContext returned by SynchronizationContext rather than a control for cross-thread marshaling.



而且,当我环顾四周时,关于为什么大多数关于 SO 上此类问题的问题的答案都建议 Invoke方法不提这个方法。

方法一:
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

方法二:
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

在哪里 SyncContextThreading.SynchronizationContext在我的 UI 表单的构造函数中定义的对象(我将它存储在一个模块中......不确定这是否是最佳选择):
Public Sub New()
InitializeComponent()
SyncContext = WindowsFormsSynchronizationContext.Current
End Sub

然后,如果我想更新 UI 表单上的控件(例如 Label1),我会这样做:
InvokeControl(Label1, Sub(x) x.Text = "hello")

或者
UIAction(Label1, Sub(x) x.Text = "hello")

那么,大家觉得呢?一种方式是首选还是取决于上下文?如果你有时间,冗长将不胜感激!

提前致谢,
布赖恩

最佳答案

好吧,我一直在做一些阅读,因为我没有得到任何回复,我想我会开始对我自己的问题进行部分回答,其中包含我迄今为止发现的内容:

我找到了 interesting codeproject article讨论 SynchronizationContext 的使用用于线程之间的编码代码(特别是从工作线程到 UI 线程)。我发现一些有趣的观察结果:

  • UI 线程的 SynchronizationContext对象是在该线程中创建第一个控件时创建的。在此之前,它没有定义。
  • SynchronizationContext UI 线程不是 SynchronizationContext 的实例类,但属于 System.Windows.Forms.WindowsFormsSynchronizationContext派生自 SynchronizationContext 的类.正是这个类定义了 Post 的行为。/Send允许将代码从一个线程编码到另一个线程。
  • 通过 UI 线程的 SynchronizationContext 的呼吁而不是使用Invoke是您不必在逻辑中保留对 UI 表单的引用即可调用它。
  • Post方法似乎很适合完成指标更新之类的事情,因为它是非阻塞的,但是,正如文章所指出的,在发布的代码中引发的异常会在 UI 线程中引发。即,发布到 UI 的代码中的错误可能会使 UI 崩溃。 Send没有这个问题。发送时抛出的异常在工作线程中抛出。


  • 更新:这里是 another insightful article .在本文中,Kael Rowan 讨论了使用 SynchronizationContext 的上下文。可能比控制实例的 Invoke 更可取/ BeginInvoke方法。他认为,在编写可重用库时,不希望仅仅为了调用目的而必须维护对库外部控件的引用。他为委托(delegate)提供代码,确保创建的任何新线程都将共享 UI 线程的 SynchronizationContext。 .

    好吧,好吧,看来我不会在这里得到任何评论了。我在这里写的内容与我的无知所允许的答案差不多。如果有人要添加其他内容,我当然会很感激,但我现在要继续前进。 :/

    关于VB.NET 两种不同的通用跨线程操作方法;哪个更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4998734/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com