好的,我在使用System.Threading.Tasks中的.Net 4.0并行扩展进行实验。我发现了一些看起来很奇怪的行为,但我认为我只是做错了什么。我有一个接口和几个实现类,它们对于这个例子来说非常简单。
interface IParallelPipe
{
void Process(ref BlockingCollection<Stream> stream, long stageId);
}
class A:IParallelPipe
{
public void Process(ref BlockingCollection<Stream> stream, long stageId)
{
//do stuff
}
}
class B:IParallelPipe
{
public void Process(ref BlockingCollection<Stream> stream, long stageId)
{
//do stuff
}
}
然后我有一个类来开始这些操作。在这里出现了问题。我基本上通过传入的类型获取关于要调用的实现类的信息,然后调用工厂来实例化它,然后使用它创建任务并启动它。如下所示:
BlockingCollection<Stream> bcs = new BlockingCollection<Stream>();
foreach (Stage s in pipeline.Stages)
{
IParallelPipe p = (IParallelPipe)Factory.GetPipe(s.type);
Task.Factory.StartNew(() => p.Process(ref bcs, s.id));
}
在我的样例中,每次运行时pipeline.Stages包含两个元素,一个被实例化为类A,另一个被实例化为类B。这很好,在调试器中我看到p带有两种不同类型。然而,类B从未被调用,相反我得到了两次调用A.Process(...)方法。两者都包含传入的stageId(即两次调用具有不同的stageIds)。
现在,如果我稍微分离一下内容,仅供测试,我可以通过像这样做来使事情正常工作:
BlockingCollection<Stream> bcs = new BlockingCollection<Stream>();
A a = null;
B b = null;
foreach (Stage s in pipeline.Stages)
{
IParallelPipe p = (IParallelPipe)Factory.GetPipe(s.type);
if(p is A)
a = p;
else
b = p;
}
Task.Factory.StartNew(() => a.Process(ref bcs, idThatINeed));
Task.Factory.StartNew(() => b.Process(ref bcs, idThatINeed));
这将调用适当的类!
有什么想法吗?