利用BackgroundWorker的关于WinForms控件的GUI操作的跨线程调用? [英] Exploiting the BackGroundWorker for cross-thread invocation of GUI actions on Winforms controls?

查看:137
本文介绍了利用BackgroundWorker的关于WinForms控件的GUI操作的跨线程调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我自己的经验与多线程的WinForms应用程序,以及问题的启发,如

Inspired by my own experience with multithreaded Winforms applications, as well as questions such as

  • <一个href="http://stackoverflow.com/questions/1364116/avoiding-the-woes-of-invoke-begininvoke-in-cross-thread-winform-event-handling">Avoiding调用/的BeginInvoke的跨线程的WinForm事件处理的困境?
  • <一个href="http://stackoverflow.com/questions/1874728/avoid-calling-invoke-when-the-control-is-disposed">Avoid调用调用当控制设置
  • Avoiding the woes of Invoke/BeginInvoke in cross-thread WinForm event handling?
  • Avoid calling Invoke when the control is disposed

我想出了一个很简单的图案,其合理性,我想核实。

I've come up with a very simple pattern, whose soundness I would like to verify.

基本上我创建(和整个应用程序的生命周期中运行)一个BGW,其唯一目的是调用请求的同步。试想一下:

Basically I'm creating (and running throughout the application's lifetime) a BGW whose sole purpose is the synchronization of invoke requests. Consider:

public MainForm()
{
    InitializeComponent();
    InitInvocationSyncWorker();
}

private void InitInvocationSyncWorker()
{
    InvocationSync_Worker.RunWorkerAsync();
}

private void InvocationSync_Worker_DoWork(object sender, DoWorkEventArgs e)
{
    Thread.Sleep(Timeout.Infinite);
}

void InvokeViaSyncWorker(Action guiAction)
{
    InvocationSync_Worker.ReportProgress(0, guiAction);
}

private void InvocationSync_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    if (IsDisposed) return; //we're in the GUI thread now, so no race condition right?

    var action = (Action) e.UserState;
    action();
}

public void SomeMethodCalledFromAnyThread() //Sample usage
{
    InvokeViaSyncWorker(() => MyTextBox.Text = "Hello from another thread!"));    
}

当然,这不是最经济的方式(保持一个线程活着那样),但如果它的作品,我没有错过任何东西,它肯定是我见过的最简单的。

Granted, it's not the most economical of approaches (keeping a thread alive like that), but if it works and I haven't missed anything, it sure is the simplest I've seen.

反馈强烈AP preciated!

Feedback is highly appreciated !

推荐答案

有没有需要打开一个线程就是为了这一点。只需使用的SynchronizationContext ,像这样:

There's no need to open a thread just for that. Simply use SynchronizationContext, like so:

private readonly SynchronizationContext _syncContext;

public MainForm()
{
    InitializeComponent();

    _syncContext = SynchronizationContext.Current;
}

void InvokeViaSyncContext(Action uiAction)
{
    _syncContext.Post(o =>
    {
        if (!IsDisposed) uiAction();
    }, null);
}

public void SomeMethodCalledFromAnyThread() //Sample usage
{
    InvokeViaSyncContext(() => MyTextBox.Text = "Hello from another thread!"));    
}

这篇关于利用BackgroundWorker的关于WinForms控件的GUI操作的跨线程调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆