我有一些代码,我需要运行在不同的线程,而不是GUI,因为它目前导致窗体冻结,而代码运行(10秒左右)。
假设我以前从未创建过一个新线程;有什么简单/基本的例子,如何做到这一点在c#和使用。net Framework 2.0或更高版本?
我有一些代码,我需要运行在不同的线程,而不是GUI,因为它目前导致窗体冻结,而代码运行(10秒左右)。
假设我以前从未创建过一个新线程;有什么简单/基本的例子,如何做到这一点在c#和使用。net Framework 2.0或更高版本?
当前回答
BackgroundWorker似乎是您的最佳选择。
下面是我的最小示例。在你点击按钮后,后台工作人员将开始在后台线程工作,并同时报告其进度。它也将在工作完成后报告。
using System.ComponentModel;
...
private void button1_Click(object sender, EventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
// this allows our worker to report progress during work
bw.WorkerReportsProgress = true;
// what to do in the background thread
bw.DoWork += new DoWorkEventHandler(
delegate(object o, DoWorkEventArgs args)
{
BackgroundWorker b = o as BackgroundWorker;
// do some simple processing for 10 seconds
for (int i = 1; i <= 10; i++)
{
// report the progress in percent
b.ReportProgress(i * 10);
Thread.Sleep(1000);
}
});
// what to do when progress changed (update the progress bar for example)
bw.ProgressChanged += new ProgressChangedEventHandler(
delegate(object o, ProgressChangedEventArgs args)
{
label1.Text = string.Format("{0}% Completed", args.ProgressPercentage);
});
// what to do when worker completes its task (notify the user)
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
delegate(object o, RunWorkerCompletedEventArgs args)
{
label1.Text = "Finished!";
});
bw.RunWorkerAsync();
}
注意:
我把所有东西都放在一个方法里 使用c#的匿名方法 简单但你总是可以拉 他们想出了不同的方法。 在里面更新GUI是安全的 ProgressChanged或 RunWorkerCompleted处理程序。 但是,从DoWork更新GUI 将会导致 InvalidOperationException。
其他回答
ThreadPool。QueueUserWorkItem对于简单的东西来说是非常理想的。唯一需要注意的是从另一个线程访问控件。
System.Threading.ThreadPool.QueueUserWorkItem(delegate {
DoSomethingThatDoesntInvolveAControl();
}, null);
如果你想得到一个值:
var someValue;
Thread thread = new Thread(delegate()
{
//Do somthing and set your value
someValue = "Hello World";
});
thread.Start();
while (thread.IsAlive)
Application.DoEvents();
如果你打算使用原始线程对象,那么你需要将IsBackground设置为true,你还应该设置Threading Apartment模型(可能是STA)。
public static void DoWork()
{
// do some work
}
public static void StartWorker()
{
Thread worker = new Thread(DoWork);
worker.IsBackground = true;
worker.SetApartmentState(System.Threading.ApartmentState.STA);
worker.Start()
}
如果你需要UI交互,我会推荐BackgroundWorker类。
在. net中有许多运行独立线程的方法,每种方法都有不同的行为。你需要在GUI退出后继续运行线程吗?您需要在线程和GUI之间传递信息吗?线程是否需要更新GUI?线程应该完成一个任务然后退出,还是继续运行?这些问题的答案会告诉你该使用哪种方法。
在Code Project网站上有一篇很好的异步方法文章,描述了各种方法并提供了示例代码。
注意,本文是在async/await模式和任务并行库引入。net之前编写的。
这是另一种选择:
Task.Run(()=>{
//Here is a new thread
});