我想知道在哪里可以获得多线程或异步线程的示例。
在我忙于处理的应用程序中,我必须在应用程序的后台运行一个线程来获取一个正在变化的值。每当这个值达到一定数量时,它就需要调用另一个函数。所有这些都必须在程序的后台运行,以便用户仍然可以在应用程序上执行其他操作。
任何可以提供帮助的示例或链接将不胜感激。
我想知道在哪里可以获得多线程或异步线程的示例。
在我忙于处理的应用程序中,我必须在应用程序的后台运行一个线程来获取一个正在变化的值。每当这个值达到一定数量时,它就需要调用另一个函数。所有这些都必须在程序的后台运行,以便用户仍然可以在应用程序上执行其他操作。
任何可以提供帮助的示例或链接将不胜感激。
为了总结这些选项,我将尝试在此处列出它们(也许将其设为社区 wiki 是个好主意)。
首先,您可以简单地在另一个线程中启动一个函数:
Thread t = new Thread( ThreadProc );
t.Start();
// now you can wait for thread to finish with t.Join() or just continue
// Thread.IsBackground allows to control how thread lifetime influences
// the lifetime of the application
...
static void ThreadProc() {...} // can also be non-static, but for simplicity....
然后你可以使用BackgroundWorker
:
BackgroundWorker bgWorker = new BackgroundWorker();
bgWorker.DoWork += MyFunction;
bgWorker.RunWorkerAsync();
voud MyFunction(object o, DoWorkEventArgs args) {...}
您可以使用ProgressChanged
和RunWorkerCompleted
事件进行更多控制(以及WorkerReportsProgress
和其他属性)
ThreadPool
如果您的方法不会花费太多时间,另一种选择是使用:
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));
...
static void ThreadProc(Object stateInfo) { ... }
还有一个选择是请BeginInvoke
一个代表:
public delegate int MyDelegate(...);
MyDelegate del = SomeFunction;
IAsyncResult ar = del.BeginInvoke(...);
int result = del.EndInvoke(ar);
这将在线程池中的线程上执行。如果您需要等待调用线程,您可以使用IAsyncResult.IsCompleted
,但它会阻塞调用线程。
当然,您可以使用Task
:
var task = Task.Factory.StartNew(() => MyMethod());
这也将MyMethod
在线程池中的线程上执行,因此适用相同的警告(尽管您可以使用它TaskCreationOptions.LongRunning
来确保始终创建新线程)。在某些情况下(当您等待任务时)它甚至可以在同一个线程上执行,但它已经过优化,因此您不必担心。
这可能是在简单性与控制之间取得最佳折衷的选择(当然,没有真正的“最佳”)。以下是好处(从乔恩斯基特的回答中无耻地窃取):
好吧,取决于您寻求的控制级别,BackgroundWorker
可以轻松工作并在System.ComponentModel.BackgroundWorker
. 现在这里是有关该主题的 MSDN 文档的链接:http: //msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
一个简单的用例场景是这样的:
BackgrouWorker BG = new BackgroudWorker();
GB.DoWork += YourFunctionDelegate(object Sender, EventArgs e);
GB.RunWorkerAsync();
现在YourFunctionDelegate(object Sender,EventArgs e)
应该是您想要在后台运行的任何内容。但是需要遵循这种参数形式,还有大量与 backgroundworker 相关的辅助函数,例如onProgressChanged
允许监视明显进度的事件,如果您是线程新手,如果您尝试这样做,一开始可能会很痛苦你自己的线程。
如果您想更多地控制执行以及线程的功能,您应该在这里查看 Task-Parallel-Library:http: //msdn.microsoft.com/en-us/library/dd460717.aspx其中有大量关于多线程的信息。
这里还有一个关于如何创建 C# 线程的精彩教程:http: //support.microsoft.com/default.aspx ?scid=kb;en-us;815804
有关 .Net 4.5 中 Windows 8 异步编程的概述:
http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx
对于 .Net 4.0 及更早版本,您可以使用 ThreadPool
System.Threading.ThreadPool.QueueUserWorkItem(obj =>
{
// Do some work
for (int i = 0; i < 1000; i++)
Math.Sin(i);
// Get back to the UI thread
App.Current.MainWindow.Dispatcher.BeginInvoke(
new Action(delegate
{
block.Text = "Done!";
}));
});
我有一篇博文比较和对比了后台任务的各种实现,每个都有优点和缺点。剧透:Task
绝对是最好的选择。另外,我推荐Task.Run
over TaskFactory.StartNew
。
如果您的后台操作是真正异步的,那么您可能根本不需要任何后台线程。LINQPad 有一组async
示例,它们是一个很好的起点。这些比其他人推荐的线程(由同一作者)章节更新。