【发布时间】:2012-02-24 18:12:25
【问题描述】:
在下面的代码中,我使用 CancellationToken 来唤醒 GetConsumingEnumerable() 当生产者不生产并且我想跳出 foreach 并退出任务时。但我没有看到 IsCancellationRequested 被记录,并且我的 Task.Wait(timeOut) 等待完整的超时时间。我做错了什么?
userToken.Task = Task.Factory.StartNew(state =>
{
userToken.CancelToken = new CancellationTokenSource();
foreach (var broadcast in userToken.BroadcastQueue.GetConsumingEnumerable(userToken.CancelToken.Token))
{
if (userToken.CancelToken.IsCancellationRequested)
{
Log.Write("BroadcastQueue IsCancellationRequested");
break;
...
}
}
return 0;
}, "TaskSubscribe", TaskCreationOptions.LongRunning);
稍后...
UserToken.CancelToken.Cancel();
try
{
task.Wait(timeOut);
}
catch (AggregateException ar)
{
Log.Write("AggregateException " + ar.InnerException, MsgType.InfoMsg);
}
catch (OperationCanceledException)
{
Log.Write("BroadcastQueue Cancelled", MsgType.InfoMsg);
}
【问题讨论】:
-
您的第一个 sn-p 是通过匿名方法运行的吗?
-
我在实现
ThreadStart委托时遇到了类似的问题。我的解决方案是将本地属性设置为静态(我知道这是不好的做法,但它有效)。在您的情况下,这似乎不是一个选项,所以我有兴趣阅读您的答案。 -
好吧,我重构了代码以使用函数而不是匿名函数,并且取消工作正常。任务开始现在看起来像这样 userToken.Task = Task.Factory.StartNew(state => SubscribeTask(userToken, receiveSendEventArgs, request, tokenId), "TaskSubscribe", TaskCreationOptions.LongRunning);
-
我开始了一项赏金活动,以帮助为这个原因找到一个明确的答案。到目前为止,我们都看到的行为毫无意义。希望有人能够详细说明。
-
@Spud 并没有真正重构,因为您更改了二进制文件的行为。
标签: c# cancellation blockingcollection