Task.Factory.StartNew“action”参数和更高级别的局部变量

时间:2010-12-03 03:13:50

标签: c# asynchronous parallel-processing taskfactory

考虑一下:

void StartUpdate(DataRequest dataRequest)
{
    Task.Factory.StartNew(request => {... do something with "request" ...}, 
        dataRequest);
}

现在,我的问题是:我可以在lambda表达式中使用dataRequest,而不是将它作为第二个参数传递给StartNew方法吗?我担心的是 - 该方法将在不同的线程上执行,我不确定dataRequest在使用时是否会保持其状态。

3 个答案:

答案 0 :(得分:5)

是的,你可以。
这称为Closure;这是一个非常强大的功能。

线程安全性或缺乏线程安全性也不例外 无论是通过闭包还是通过StartNew参数获取实例,它仍然是同一个对象。 (除非它是struct,这将是难以形容的邪恶)

答案 1 :(得分:2)

我遇到了同样的问题。使用Action而不是lambda表达式。

private void StartUpdate(DataRequest dataRequest)
{
    Action<DataRequest> pobjAction = new Action<DataRequest>(DoSomething);
    Task.Factory.StartNew(pobjAccion, dataRequest);
}


private void DoSomething(DataRequest dataRequest)
{
    Trace.WriteLine(dataRequest.ToString());
}

答案 2 :(得分:1)

回答你的问题,你可以,但它可能不是线程安全的。我学习使用ThreadLocal来帮助。

在您的委托方法中,

应该隔离您的dataRequest。

ThreadLocal<DataRequest> tls = new ThreadLocal<DataRequest>();

Task.Factory.StartNew(request => {
   tls.Value = (DataRequest)stateObject;

   ///
}, dataRequest);

/ *我是从Pro .NET Parallel Programming in C# * /

获得的