Winforms在单独的线程中执行代码

时间:2009-07-20 07:34:35

标签: winforms multithreading

一个少年问题...

我意识到在Winforms应用程序中,长时间运行的代码应该在自己的线程中执行。如何实现这一点,例如按钮点击事件?

我想这样做是为了释放UI线程,以便我可以同时使用半透明模式对话框表单覆盖当前表单。我已经创建了模态对话框表单,其中有一个位于中心的整齐加载GIF,它可以完全独立于按钮点击事件。

我选择这种方法的原因是因为(1)我想在执行代码时阻止任何用户与表单的交互,以及(2)向用户提供处理正在进行的指示(I)不知道如何判断一段特定代码执行需要多长时间,因此选择了无限加载指示器gif)。

此外,关于在单独的线程中执行代码的主题......这不应该适用于任何代码,还是仅适用于长期运行的代码?

我真的很感激这方面的任何帮助!谢谢!

3 个答案:

答案 0 :(得分:9)

最简单的方法之一是使用BackgroundWorker组件。向表单添加BackgroundWorker,为DoWork事件添加事件处理程序,并从那里调用长时间运行的函数。您可以通过调用BackgroundWorker组件上的RunWorkerAsync方法在按钮单击事件处理程序中启动它。

为了知道操作何时准备就绪,请为RunWorkerCompleted事件设置处理程序。

private void Button_Click(object sender, EventArgs e)
{
    myBackgroundWorker.RunWorkerAsync();
}

private void myBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    // long-running operation here; will execute on separate thread
}

private void myBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // operation is ready
}

答案 1 :(得分:4)

我会回答你问题的后半部分(因为Fredrik已经解释过BackgroundWorker):

不,除非任务长时间运行,否则将任务移动到单独的线程是没有意义的。

在单独的线程上运行任务总会产生额外的开销。可能需要更多的UI线程时间来启动线程并处理任务完成,然后它必须首先完成任务。

与任何编程技术一样,您必须权衡特定情况的成本和收益。

答案 2 :(得分:2)

我会根据自己的经验尝试回答你问题的第二部分。 通常只在以下三种情况之一中使用线程:

  • 在系统调用(文件/套接字IO等)上阻塞显着时间段的操作

  • 在长时间运行的操作中,不希望丢失UI响应。

  • 有多个长时间运行的操作,需要利用多核环境。

正如Andrew Shepherd所说,使用Threads会产生开销。 线程使事情变得复杂。永远不要为了穿线而穿线。