目录
介绍
概念化这个混乱
编码此混乱
- 下载源11 KB
通常,Windows窗体和控件本身不是线程安全的,这会使多线程应用程序中的事情大大复杂化。本文提供了一种线程同步的替代方法,使用编组来执行从主UI线程上的辅助线程调用的一些代码。
概念化这个混乱线程化很困难,而且很容易出错,当存在同步问题时,它们很容易被追查。如果完全合理,通常我们应该在需要鲁棒代码的情况下尽可能避免多线程。
多线程会使事情复杂化的一种非常常见的情况是更新用户界面,由于Winforms线程不安全,因此通常必须从UI线程完成。
我们将通过将一些代码从调用线程编组到主UI线程,从而使代码本身在UI线程上执行,从而完全避免同步问题。由于所有与UI相关的工作都在UI线程上完成,因此没有同步问题。
输入ISynchronizeInvoke。这个小接口是一个约定,上面写着“嘿,我可以接受委托并在此线程上执行委托”,其中“this thread”是在其ISynchronizeInvoke上创建实现的线程。由于每种形式和每个控件都实现此接口,因此每个控件都可以将委托代码编组到其线程(UI线程)。我们将看到这非常有用。
编码此混乱一旦掌握了这些代码,它就非常基础。
ISynchronizeInvoke 实现四个重要成员:
- Invoke() (两个重载)在创建此实例的线程上调用给定委托中的代码
- BeginInvoke()和EndInvoke()是上述的异步版本——BeginInvoke(),不像Invoke()不会阻塞。
- InvokeRequired表示我们是否必须使用Invoke()/ BeginInvoke()安全执行。如果为假,则不必整理代理,我们可以直接调用它。这唯一的好处就是性能。不一定必须使用它。
让我们看一下源代码:
// create a thread. we use this instead of tasks
// or thread pooling simply for demonstration.
// normally, it's not a great idea to spawn
// threads directly like this.
var thread = new Thread(() => {
// fill the progress bar, slowly
for(var i = 0;i
{
// execute this code on the UI thread
Progress.Value = i / 100;
};
// this marshals the code above onto the thread
// that this form is running on (the UI thread)
// everything within the action code is executed
// on the UI thread. We only do this if
// InvokeRequired is true, otherwise we can
// invoke the delegate directly. In this example,
// it should always be true, but in the real world,
// it will not be necessarily. Calling Invoke when
// it's not necessary (InvokeRequired=false) doesn't
// hurt, but it causes unnecessary overhead.
if (InvokeRequired)
Invoke(action);
else
action();
// all controls and forms implement Invoke.
// There is also BeginInvoke/EndInvoke which
// you can use to invoke asynchronously
}
});
thread.Start();
基本上,我们在这里正在执行的是生成一个线程,并且我们希望该线程在进度条上进行更新。但是,进度条位于UI线程上,因此从另一个线程进行调用并不安全。
为了解决这个问题,而不是实现线程同步,我们可以简单地按上述方式使用Invoke(),这将使用窗体的ISynchronizeInvoke.Invoke()方法在UI线程上执行action中的所有代码。请注意,我们不能直接使用Invoke()或lambda或匿名委托BeginInvoke()。这就是为什么我们把它放在一个名为action的Action委托中。当然,这有点笨拙,但是与必须对UI实现线程安全调用相比,它有了很大的改进。