在 ActionBlock 中重新提交失败的任务
Re-Submitting a failed Task in an ActionBlock
我正在使用看起来像这样的操作块:
ActionBlock<Tuple<string,byte[],string>> ab =
new ActionBlock<Tuple<string,string,string>>(item => {
service.DoSomeAction(item.Item1, item.Item2, item.Item3);
},
new ExecutionDataflowBlockOptions {
MaxDegreeOfParallelism = 2
});
foreach(var item in Items) {
ab.Post(new Tuple<string,string,string>(item.a, item.b, item.c));
}
ab.Complete();
ab.Completion.Wait();
我的问题是 service.DoSomeAction()
可能会因网络负载而失败,我想知道 ActionBlock 是否具有请求任务的机制。
我当然可以在该调用周围添加一个 try/catch 块,并在重新抛出异常之前让 catch 块 wait/retry 几次。我正在寻找的是用相同的参数调用 ab.Post()
。我的问题是我已经在调用 ab.Complete()
。是否可以在不调用 ab.Complete()
的情况下等待 ActionBlock。我可以使用更好的工具来完成这项工作吗?
我不太了解ActionBlock
,你能用Parallel
class代替吗?
像这样:
Parallel.ForEach(Items, item =>
{
bool succeeded = false;
while(!succeeded)
{
try
{
service.DoSomeAction(item.Item1, item.Item2, item.Item3);
succeeded = true;
}
catch(MyException) //the expected Exception, let others get thrown
{
}
}
});
Is it possible to wait on an ActionBlock without calling ab.Complete()
.
是的,只是不要调用它,直接转到ab.Completion.Wait();
(旁注:如果可能,你应该使用await ab.Completion;
),BUT 其他人将需要调用 ab.Complete()
,否则它会无限期地等待,因为 ab.Completion
永远不会完成。
但是 为什么不想在操作中使用 "try/catch/retry" 逻辑? IMO 这将是更好的方法。
例如。使用 TransientFaultHandling.Core
你可以这样做:
var retry = new RetryPolicy(ErrorDetectionStrategy.On<Exception>(), // see http://pastebin.com/6tmQbkj4
3, TimeSpan.FromMilliseconds(250));
ActionBlock<Tuple<string,byte[],string>> ab =
new ActionBlock<Tuple<string,string,string>>(item =>
retry.ExecuteAction(() => service.Action(item.Item1, item.Item2, item.Item3)),
new ExecutionDataflowBlockOptions {
MaxDegreeOfParallelism = 2
});
我正在使用看起来像这样的操作块:
ActionBlock<Tuple<string,byte[],string>> ab =
new ActionBlock<Tuple<string,string,string>>(item => {
service.DoSomeAction(item.Item1, item.Item2, item.Item3);
},
new ExecutionDataflowBlockOptions {
MaxDegreeOfParallelism = 2
});
foreach(var item in Items) {
ab.Post(new Tuple<string,string,string>(item.a, item.b, item.c));
}
ab.Complete();
ab.Completion.Wait();
我的问题是 service.DoSomeAction()
可能会因网络负载而失败,我想知道 ActionBlock 是否具有请求任务的机制。
我当然可以在该调用周围添加一个 try/catch 块,并在重新抛出异常之前让 catch 块 wait/retry 几次。我正在寻找的是用相同的参数调用 ab.Post()
。我的问题是我已经在调用 ab.Complete()
。是否可以在不调用 ab.Complete()
的情况下等待 ActionBlock。我可以使用更好的工具来完成这项工作吗?
我不太了解ActionBlock
,你能用Parallel
class代替吗?
像这样:
Parallel.ForEach(Items, item =>
{
bool succeeded = false;
while(!succeeded)
{
try
{
service.DoSomeAction(item.Item1, item.Item2, item.Item3);
succeeded = true;
}
catch(MyException) //the expected Exception, let others get thrown
{
}
}
});
Is it possible to wait on an ActionBlock without calling
ab.Complete()
.
是的,只是不要调用它,直接转到ab.Completion.Wait();
(旁注:如果可能,你应该使用await ab.Completion;
),BUT 其他人将需要调用 ab.Complete()
,否则它会无限期地等待,因为 ab.Completion
永远不会完成。
但是 为什么不想在操作中使用 "try/catch/retry" 逻辑? IMO 这将是更好的方法。
例如。使用 TransientFaultHandling.Core
你可以这样做:
var retry = new RetryPolicy(ErrorDetectionStrategy.On<Exception>(), // see http://pastebin.com/6tmQbkj4
3, TimeSpan.FromMilliseconds(250));
ActionBlock<Tuple<string,byte[],string>> ab =
new ActionBlock<Tuple<string,string,string>>(item =>
retry.ExecuteAction(() => service.Action(item.Item1, item.Item2, item.Item3)),
new ExecutionDataflowBlockOptions {
MaxDegreeOfParallelism = 2
});