Far*_*ruz 6 task-parallel-library c#-4.0
我的代码运行4个函数来填充信息(使用Invoke)到类,例如:
class Person
{
int Age;
string name;
long ID;
bool isVegeterian
public static Person GetPerson(int LocalID)
{
Person person;
Parallel.Invoke(() => {GetAgeFromWebServiceX(person)},
() => {GetNameFromWebServiceY(person)},
() => {GetIDFromWebServiceZ(person)},
() =>
{
// connect to my database and get information if vegeterian (using LocalID)
....
if (!person.isVegetrian)
return null
....
});
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:如果他不是素食主义者,我不能返回null,但我希望能够停止所有线程,停止处理并返回null.如何实现?
要Parallel.Invoke
尽早退出,你必须做三件事:
AggregateException
按照Jon的答案指示捕获.IsCancellationRequested
财产,这才有意义.您的代码将如下所示:
var cts = new CancellationTokenSource();
try
{
Parallel.Invoke(
new ParallelOptions { CancellationToken = cts.Token },
() =>
{
if (!person.IsVegetarian)
{
cts.Cancel();
throw new PersonIsNotVegetarianException();
}
},
() => { GetAgeFromWebServiceX(person, cts.Token) },
() => { GetNameFromWebServiceY(person, cts.Token) },
() => { GetIDFromWebServiceZ(person, cts.Token) }
);
}
catch (AggregateException e)
{
var cause = e.InnerExceptions[0];
// Check if cause is a PersonIsNotVegetarianException.
}
Run Code Online (Sandbox Code Playgroud)
但是,正如我所说,取消令牌只有在你能查看时才有意义.所以内部应该有机会GetAgeFromWebServiceX
检查取消令牌并提前退出,否则,将令牌传递给这些方法是没有意义的.
好吧,您可以从操作中抛出异常,捕获AggregateException
(GetPerson
即在周围放置一个 try/catch 块Parallel.Invoke
),检查它是否是正确类型的异常,然后返回 null。
除了停止所有线程之外,这满足了一切。我认为除非您开始使用取消令牌,否则您不太可能轻松停止已经运行的任务。您可以通过保留一个值来指示到目前为止boolean
是否有任何任务失败,并让每个任务在开始之前进行检查来阻止进一步的任务执行......这有点难看,但它会起作用。
我怀疑使用“完整”任务而不是Parallel.Invoke
会让所有这一切变得更加优雅。
归档时间: |
|
查看次数: |
6950 次 |
最近记录: |