I'm using the tasks part of the Reactive Extensions library on .Net 3.5
It works mostly smoothly but in one place it calls the same task twice.
The call looks like this:
Task.Factory.StartNew(
() => Processor.ProcessMessage(incomingMessage),
TaskCreationOptions.PreferFairness );
Any ideas? Is this a bug?
---- update
i think the problem is with the way c# does closure in lambdas. the problem wasn"t in the TPL, the same problem returned with the plain old thread pool.
and this solved it:
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]);
}
the original source was:
foreach (var Processor in processors)
{
Task.Factory.StartNew(
() => Processor.ProcessMessage(incomingMessage),
TaskCreationOptions.PreferFairness );
}
so i have closure around Processor, and i guess the problem was it was recycling the same object for the lambda and swapping the Processor.
---- update 2
I'm convinced this is the problem. i refactored and debugged the System.Threading.dll both times i create the task, it is created with the same delegate(Same ObjectID) and the Processor changes in the Target property between iterations. anyone knows a good work around?
---- update 3 this works too(thanks Judah Himango):
foreach (var processor in processors)
{
var crap = processor;
Task.Factory.StartNew(() => crap.ProcessMessage(incomingMessage), TaskCreationOptions.PreferFairness);
}