【问题标题】:How to invoke from UI thread (C# .NET 2) [duplicate]如何从 UI 线程调用(C# .NET 2)[重复]
【发布时间】:2013-12-19 13:23:04
【问题描述】:

通常我们以这种方式在 UI 线程上调用:

myControl.Invoke((MethodInvoker)delegate() { Foo(); });

他们有没有任何方法可以在没有任何控制实例的情况下做到这一点?我的意思是这样的:

System.Windows.Forms.Thread.Invoke(...);


解决方案 dcastro 给出的解决方案,使用WindowsFormsSynchronizationContext。这是一个非常简单的表单示例:

public partial class FrmFoo : Form
{
    SynchronizationContext uiThread;

    public void FrmFoo()
    {
        // Needs to assign it from somewhere in the UI thread (in constructor for example)
        uiThread = WindowsFormsSynchronizationContext.Current;
    }

    void AsyncBar()
    {
        uiThread.Send(delegate(object state)
        {
            // UI Cross-Thread dangerous manips allowed here
        }, null);
    }
}

【问题讨论】:

  • 这确实是旧的做事方式。告诉人们您正在使用的 .NET 版本将有助于带来更现代的答案......以及一个用例。
  • @SimonWhitehead .NET 2 兼容性是技术限制,我别无选择

标签: c# multithreading winforms delegates invoke


【解决方案1】:

您可以使用当前的WindowsFormsSynchronizationContext(自 .NET 2.0 起可用)

System.Threading.SynchronizationContext.Current.Post(delegate, state);

您应该从您的 UI 线程中获取对上下文的引用,并使其可供其他线程访问,然后其他线程可以使用它在 UI 线程上执行代码。

这相当于BeginInvoke。 对于 Invoke 等效项,请改用 Send 方法。

【讨论】:

  • 从工作线程调用时,此解决方案将不起作用。
  • @Gusdor 不会,但Current 实例可以从正确的线程中捕获,并且“WindowsForms(..)”可以保护捕获其他上下文。我用解决方案示例更新我的帖子
  • @56ka 绝对!如果答案能说明这一点,我就不会对此发表评论。
  • @Gusdor 感谢您指出这一点,我已经编辑了我的答案。
【解决方案2】:

使用SynchronizationContextPost 方法

var sCon=SynchronizationContext.Current;
        sCon.Post(new SendOrPostCallback((o) => {
            //do your stuffs
        }), null);

SynchronizationContext 只是一种抽象,它代表一个 你想要做一些工作的特定环境。作为一个例子 在这样的环境中,Windows 窗体应用程序有一个 UI 线程(虽然它是 出于本讨论的目的,可能有多个 没关系),这是任何需要使用UI的工作 需要进行控制。对于您在 ThreadPool 线程,您需要将工作编组回 UI,以便 这项工作可以与 UI 控件混为一谈,Windows 窗体提供了 Control.BeginInvoke 方法。你给一个控制的委托 BeginInvoke 方法,并且该委托将在 与该控件关联的线程。

【讨论】:

  • 来自 msdn: Gets the synchronization context for the current thread. 从工作线程调用时,此解决方案将不起作用 - SynchronizationContext.Current 将返回 null 或更糟,默认上下文。
  • 这是第一步,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-11
  • 1970-01-01
  • 2015-02-17
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
相关资源
最近更新 更多