我想更好地理解我在C#中使用的异步和并行选项。在下面的片段中,我列出了我遇到的最多的5种方法。但我不知道该如何选择 - 或者更好的是,在选择时要考虑什么样的标准:处理列表的C#异步选项
方法1:任务
(见http://msdn.microsoft.com/en-us/library/dd321439.aspx)
调用StartNew在功能上等同使用它的一个构造函数创建一个Task,然后调用Start来安排它执行。但是,除非创建和调度必须分开,否则StartNew是推荐的简单性和性能方法。
TaskFactory的StartNew方法应该是创建和计划计算任务的首选机制,但对于那些创建和计划必须分开的情况,可以使用构造函数,然后将任务的开始方法可用于调度稍后执行的任务。
// using System.Threading.Tasks.Task.Factory
void Do_1()
{
var _List = GetList();
_List.ForEach(i => Task.Factory.StartNew(_ => { DoSomething(i); }));
}
方法2:QueueUserWorkItem
(见http://msdn.microsoft.com/en-us/library/system.threading.threadpool.getmaxthreads.aspx)
系统内存让您可以排队尽可能多的线程池的请求。如果有更多的请求比线程池线程多,则额外的请求会保持排队,直到线程池线程可用。
可以放置在其中定义该方法的类的实例字段由排队方法所需的数据,也可以使用接受包含必要数据的对象的QueueUserWorkItem(WaitCallback,对象)的过载。
// using System.Threading.ThreadPool
void Do_2()
{
var _List = GetList();
var _Action = new WaitCallback((o) => { DoSomething(o); });
_List.ForEach(x => ThreadPool.QueueUserWorkItem(_Action));
}
方法3:Parallel.Foreach
(参见:http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx)
并行类提供基于库的数据以便共同操作,如并行替换循环,每个循环以及执行一组语句。
对源enumerable中的每个元素调用一次body委托。它以当前元素作为参数提供。
// using System.Threading.Tasks.Parallel
void Do_3()
{
var _List = GetList();
var _Action = new Action<object>((o) => { DoSomething(o); });
Parallel.ForEach(_List, _Action);
}
方法4:IAsync。的BeginInvoke
(参见:http://msdn.microsoft.com/en-us/library/cc190824.aspx)
BeginInvoke的是异步的;因此,控件在被调用后立即返回给调用对象。
// using IAsync.BeginInvoke()
void Do_4()
{
var _List = GetList();
var _Action = new Action<object>((o) => { DoSomething(o); });
_List.ForEach(x => _Action.BeginInvoke(x, null, null));
}
方法5:BackgroundWorker的
(参见:http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx)
要为一个后台操作,添加一个事件处理程序事件的DoWork。在此事件处理程序中调用您的耗时操作。要启动该操作,请调用RunWorkerAsync。要接收进度更新通知,请处理ProgressChanged事件。要在操作完成时接收通知,请处理RunWorkerCompleted事件。
// using System.ComponentModel.BackgroundWorker
void Do_5()
{
var _List = GetList();
using (BackgroundWorker _Worker = new BackgroundWorker())
{
_Worker.DoWork += (s, arg) =>
{
arg.Result = arg.Argument;
DoSomething(arg.Argument);
};
_Worker.RunWorkerCompleted += (s, arg) =>
{
_List.Remove(arg.Result);
if (_List.Any())
_Worker.RunWorkerAsync(_List[0]);
};
if (_List.Any())
_Worker.RunWorkerAsync(_List[0]);
}
}
我想明显的critieria是:
- 是比任何其他获得更好的性能?
- 错误处理是否比其他更好?
- 对于监测/反馈,是否比另一个更好?
但是,如何你选择? 提前感谢您的见解。
你也可以看看System.Reactive(被动扩展,或rx.net)。 – lbergnehr
而你甚至没有碰过异步CTP! :-) – xanatos
的确如此,但我坚持使用C#4。好点,但。 –