在 Windows.Forms 中执行后台任务的最简单方法是什么?

ros*_*eld 5 .net multithreading design-patterns winforms

后台任务涉及网络 I/O、磁盘 I/O 或其他可能或可能不通过网络发生的长时间运行的任务。它通常会与更新 GUI 的代码混合在一起,而后者需要在另一个线程(GUI 线程)上运行。

简单的意思是,当打开 Form.cs 文件时,源代码比以前更容易或更容易阅读。实际上,源代码流仍然必须按照代码执行的顺序顺序读取,无论它在哪个线程上执行。所有支撑结构必须可重复使用并隐藏在某个地方,而不是包含在每个表格中。

谷歌搜索MSDN:发现微软官方认可的解决方案是System.ComponentModel.BackgroundWorker,它在第二点上(非常!)不足。

(System.Windows.Threading.Dispatcher 中还有一个官方认可的 Silverlight/XAML/3.5 解决方案模型。)

ros*_*eld 1

这是迄今为止我想到的最简单的想法。这可能完全不符合犹太教规,我编写的 Windows.Forms 应用程序非常接近于零。

它涉及一个助手,它有两个主要方法:Background() 和 Foreground()。其中任何一个都采用以 lambda 表达式形式指定的委托。Background() 在后台线程上启动任何给定的委托并立即返回。Foreground() 使用 Form.BeginInvoke() 将任何给定的委托“返回”到 GUI 线程并立即返回。

下面是如何使用此设计模式的代码示例,前提是已经实现了帮助程序。

public class Form1 : Form {
    protected ProgressBar progressBar1;
    protected Button button1;

    protected BackgroundHelper helper = new BackgroundHelper();

    public void button1_Click(...) {
        // Execute code in the background.
        helper.Background(() => {
            for (int i = 0; i <= 100; i++) {
                // Continually report progress to user.
                helper.Foreground<int>(i, j => {
                    progressBar1.Value = j;
                });
                // Simulate doing I/O or whatever.
                Thread.Sleep(25);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

这使代码保持整齐的顺序,在适当的位置提供共享变量,并允许跨越两个线程的循环。

为了澄清助手的作用,

  • 构造函数启动一个等待队列的后台线程。
  • Background() 和 Foreground() 都会立即返回。
  • Background() 使用内部队列将代码排入后台线程中运行。
  • Foreground() 执行相同的操作,并在首先创建帮助器的 GUI 线程上使用 BeginInvoke。

编辑:实施: http:
//code.google.com/p/backgrounder/