问题描述
灵感来自我自己使用多线程 Winforms 应用程序的经验,以及诸如
Inspired by my own experience with multithreaded Winforms applications, as well as questions such as
- 避免调用的麻烦/BeginInvoke 在跨线程 WinForm 事件处理中?
- 避免在释放控件时调用 Invoke
我想出了一个非常简单的模式,我想验证它的可靠性.
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.
非常感谢您的反馈!
推荐答案
没有必要为此开一个线程.只需使用 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 (IsHandleCreated && !IsDisposed) uiAction();
}, null);
}
public void SomeMethodCalledFromAnyThread() //Sample usage
{
InvokeViaSyncContext(() => MyTextBox.Text = "Hello from another thread!"));
}
这篇关于利用 BackGroundWorker 跨线程调用 Winforms 控件上的 GUI 操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!