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

2024-04-05

VB.NET 2010、.NET 4

Hello,

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

更新:这个问题的部分原因是来自以下陈述:MSDN 页面上Control.InvokeRequired http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invokerequired.aspx.

更好的解决方案是使用SynchronizationContext由返回SynchronizationContext而不是一个 跨线程封送控制。

而且,当我环顾四周时,人们普遍感到困惑的是,为什么大多数关于此类问题的答案都表明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

Where SyncContext is a Threading.SynchronizationContext我的 UI 表单的构造函数中定义的对象(我将其存储在模块中......不确定这是否是最佳选择):

Public Sub New()
    InitializeComponent()
    SyncContext = WindowsFormsSynchronizationContext.Current
End Sub

然后,如果我想更新一个控件(例如,Label1)在 UI 表单上,我会这样做:

InvokeControl(Label1, Sub(x) x.Text = "hello")

or

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

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

提前致谢,
Brian


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

我找到了一个有趣的代码项目文章 http://www.codeproject.com/KB/threads/SynchronizationContext.aspx讨论使用SynchronizationContext用于在线程之间(特别是从工作线程到 UI 线程)编组代码。我发现一些有趣的观察:

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

更新:这是另一篇富有洞察力的文章 http://blogs.msdn.com/b/kaelr/archive/2007/09/05/synchronizationcallback.aspx。在本文中,Kael Rowan 讨论了使用SynchronizationContext可能比控制实例更好Invoke/BeginInvoke方法。他认为,在编写可重用库时,仅仅出于调用目的而必须维护对库外部控件的引用是不可取的。他为委托提供了代码,确保创建的任何新线程都将共享 UI 线程的SynchronizationContext.

好吧,看来我不会再在这里收到任何评论了。我在这里写的内容是我的无知使我能够得到的最接近的答案。如果有人还有什么要补充的,我肯定会很感激,但我现在要继续了。 :/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 为什么在读取字典时要锁定

    我对我正在阅读的一本关于线程的书 C 3 in a Nutshell 中的代码列表感到困惑 在 应用程序服务器中的线程安全 主题中 给出了以下代码作为 UserCache 的示例 static class UserCache static
  • 为什么Apache MPM prefork.c 使用互斥体来保护accept()?

    我坐下来读书Apache 的 MPM prefork c http code metager de source xref apache httpd server mpm prefork prefork c这段代码使用了一个名为accept
  • 在 Three.js 中从 Web Worker 加载纹理

    当将大纹理图像应用到网格上一段明显的时间时 Three js 会锁定浏览器的主线程 让我们考虑以下示例 var texLoader new THREE TextureLoader texLoader load someLargeTextur
  • 创建具有特定权限的线程C++

    我有一个多线程应用程序 我想创建一个具有不同用户权限的线程 例如 多域管理员权限 但我找不到任何 Win32 APICreateThread要做到这一点 如何创建具有特定用户权限的线程 thanks 调用 CreateThread CREA
  • 将字符串转换为双精度 - VB

    VB中有没有一种有效的方法来检查字符串是否可以转换为双精度型 我目前正在尝试将字符串转换为双精度型 然后查看它是否引发异常 但这似乎减慢了我的申请速度 Try if number then format it current CDbl x
  • 如何使用 wait() 和 notification() 正确暂停线程

    我想要一个启动线程并提供暂停和继续该线程的方法的类 我的第一个方法是使用标志 只要该值为 true 它就会循环 sleep 方法 就像是 public class Bot private Thread t private boolean i
  • 将数据从一个线程传递到另一个线程的最快可能方法

    我正在使用增强spsc queue将我的东西从一个线程移动到另一个线程 这是我的软件中的关键位置之一 所以我想尽快完成它 我写了这个测试程序 include
  • scala 提供类似 C++ 模板的东西吗?

    我来自 C 并试图了解 scala 的类型系统 考虑以下 C 模板类 template
  • 使用 boost::thread 特定的 ptr<>::get() 是否会很慢?有什么解决方法吗?

    我目前正在使用 Valgrind 的 Callgrind 分析一个存在性能问题的应用程序 在查看分析数据时 似乎有 25 的处理时间花费在boost detail get tss data在主要目的是物理模拟和可视化的应用程序中 get t
  • 通过推送通知唤醒

    Suppose 有一些对象 例如 一个数组a 和依赖于对象的条件 例如 a empty 当前线程以外的某些线程可以操作该对象 a 因此条件评估值的真实性会随着时间的推移而变化 如何让当前线程在代码中的某个时刻休眠 并在条件满足时通过推送通知
  • 如何限制Erlang VM(BEAM)使用的核心数量?

    我正在具有 2 个四核 Xeon E5520 2 2GHz 24 0GB RAM 和 Erlang R15B02 启用 SMP 的节点上运行实验 我想知道是否可以限制Erlang VM使用的核心数量 以便我可以暂时禁用一些核心并逐步增加数量
  • 除非在后台线程中获取新的引用,否则存在潜在的引用计数问题

    我有一个second https stackoverflow com questions 28898966 prefer property accessor or kvc style for accessing core data prop
  • fprintf() 线程安全吗?

    我正在为野人就餐问题的某些变量编写一个 C 解决方案 现在 我创建线程 每个线程都将 FILE 获取到同一个调试文件 在线程内我正在使用 fprintf 进行一些打印 打印的语句不受任何类型的互斥锁等保护 我没有在调试文件中观察到任何交错行
  • java中如何参数化泛型单例

    我有下一个问题 我有一个界面 public interface Worker
  • 这个等待通知线程语义的真正目的是什么?

    我刚刚遇到一些代码 它使用等待通知构造通过其其他成员方法与类中定义的线程进行通信 有趣的是 获取锁后 同步范围内的所有线程都会在同一锁上进行定时等待 请参见下面的代码片段 随后 在非同步作用域中 线程执行其关键函数 即 做一些有用的事情1
  • Erlang 如何睡觉(晚上?)

    我想在 Erlang 服务器上每隔几个小时运行一次小型清理过程 我知道计时器模块 我在教程中看到一个示例 使用链式计时器 睡眠命令来等待几天后发生的事件 我觉得这很奇怪 我知道 Erlang 进程与其他语言中的进程相比是独一无二的 但是进程
  • 从 Invoke 方法获取 RETURN

    我正在尝试从另一个线程上的列表框项目中读取值 我尝试创建一种新方法来运行调用命令 我可以设法将命令发送到列表框 例如通过调用方法添加 但我似乎无法得到响应 我似乎无法获取该项目的值 我尝试了几种方法 一旦我将它从空变为字符串 事情就开始变得
  • java中使用多线程调用同一类的不同方法

    我有一个类 如下所示 具有三种方法 public class MyRunnable implements Runnable Override public void run what code need to write here to c
  • 下载需要使用 vb.net/c# 进行身份验证的文件?

    与 CSV 文件类似 可以从以下位置下载http download finance yahoo com d quotes csv s RHT 如何下载需要身份验证的文件 我可以简单地使用 My Computer Network Downlo
  • 如何打开 Windows 资源管理器窗口并选择特定文件夹

    我有一个 winform 应用程序 这个 winform 应用程序创建了几个文件 我想在我的应用程序中实现 查找目标 功能来显示这些文件 这些文件位于同一文件夹中 看图片 假设我创建了几个文件 C Test 文件夹 该文件夹包含以下文件 C

随机推荐