AK_*_*AK_ 4 .net c# multithreading system.reactive
我正在使用.Net 3.5上的Reactive Extensions库的任务部分
它大部分工作顺利,但在一个地方它调用相同的任务两次.
电话看起来像这样:
Task.Factory.StartNew(
() => Processor.ProcessMessage(incomingMessage),
TaskCreationOptions.PreferFairness );
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?这是一个错误吗?
----更新
我认为问题在于c#在lambdas中关闭的方式.问题不在TPL中,与普通旧线程池一起返回同样的问题.
这解决了它:
foreach (var Processor in processors)
{
object[] crap = new object[2];
crap[0] = Processor;
crap[1] = incomingMessage;
Task.Factory.StartNew(Magic, crap, TaskCreationOptions.PreferFairness);
}
public void Magic(object obj)
{
object[] crap =(object[]) obj;
((IIncomingMessageProcessor)crap[0]).ProcessMessage((IncomingMessageBase)crap[1]);
}
Run Code Online (Sandbox Code Playgroud)
原始来源是:
foreach (var Processor in processors)
{
Task.Factory.StartNew(
() => Processor.ProcessMessage(incomingMessage),
TaskCreationOptions.PreferFairness );
}
Run Code Online (Sandbox Code Playgroud)
所以我在处理器周围关闭,我想问题是它为lambda回收相同的对象并交换处理器.
----更新2
我确信这是问题所在.我在创建任务时重构和调试了System.Threading.dll,它是使用相同的委托(Same ObjectID)创建的,并且处理器在迭代之间的Target属性中发生了变化.谁知道一个好的工作?
----更新3这也有效(感谢Judah Himango):
foreach (var processor in processors)
{
var crap = processor;
Task.Factory.StartNew(() => crap.ProcessMessage(incomingMessage), TaskCreationOptions.PreferFairness);
}
Run Code Online (Sandbox Code Playgroud)
你在lambda中使用循环变量吗?例如
foreach (var foo in blah)
{
// You're capturing foo inside a lambda -- this probably won't do what you think it will!
Task.Factory.StartNew(() => foo.Something());
}
Run Code Online (Sandbox Code Playgroud)
更新2012年11月:新的C#5编译器通过改变捕获foreach循环变量的行为(即预期行为)来解决这一混乱领域.C#团队的Eric Lippert 写道,
我们正在进行重大改变.在C#5中,foreach的循环变量将在逻辑上位于循环内部,因此闭包每次都会关闭变量的新副本."for"循环不会改变.
| 归档时间: |
|
| 查看次数: |
2128 次 |
| 最近记录: |