xar*_*tal 7 c# asynchronous exception-handling task-parallel-library async-await
我不确定在代码中对事件作出反应的两种可能性.大多数情况下,我担心哪一个需要更少的资源.我有一个观察者注册的方法eventproducer.如果eventproducer返回某个东西,则该方法退出并且该方法的调用者再次启动该方法(您可以将其视为一种长轮询).
在eventproducer有时触发大量每秒的事件,有时休息几分钟.
第一种方法是等待500毫秒的延迟,然后检查是否有东西返回或以其他方式(直到超时5分钟)再次延迟500毫秒.
eventProducer.RegisterListener((events)=>{evList.Add(events)});
while(evList.Count=0 && !TimeOut){
await Task.Delay(500);}
eventProducer.UnRegister(...);
// return evList, method gets recalled immediately
Run Code Online (Sandbox Code Playgroud)
第二种方法是使用a CancellationToken.如果eventproducer产生某些东西,则CancellationTokenSource取消源.在等待的方法中Task.Delay(5min, cancellationToken).
eventProducer.RegisterListener((events)=>{evList.Add(events);
cancelSource.Cancel();}
try
{
await Task.Delay(5min, cancellationToken)
}
catch(TaskCanceledException){//nothing to do};
eventProducer.UnRegister(...);
// return evList, method gets recalled immediately
Run Code Online (Sandbox Code Playgroud)
第二种方法的优点是,如果生产者生产某种东西,并且我们不必在循环中等待和唤醒,该方法立即返回.
但是,每当制作人产生某种东西时,第二种方法TaskCanceledException就是抛出.我担心这会比清醒更能影响系统负载,等待每500毫秒,尤其是当eventproducer产生大量事件时.
我是否过高估计抛出和捕获异常的成本?有没有办法取消Task.Delay一个CancellationToken但没有投掷TaskCanceledException?IE之类的东西task.setComplete?
i3a*_*non 15
如果你想要一个类似于取消给你的即时通知,但没有例外,你可以简单地使用TaskCompletionSource.
TaskCompletionSource是你如何创建一个承诺任务.您将从Task酒店获得一项未完成的任务,然后您完成(或取消)SetResult.您可以使用它来实际传递结果本身:
var tcs = new TaskCompletionSource<Events>();
eventProducer.RegisterListener(events => tcs.SetResult(events));
var result = await tcs.Task;
eventProducer.UnRegister(...);
Run Code Online (Sandbox Code Playgroud)
此解决方案没有任何例外,也不使用不必要的轮询
回答您的具体问题:
我是否过高估计抛出和捕获异常的成本?
大概.你需要测试并证明它确实是一个问题.
有没有办法取消Task.Delay与
CancellationToken但没有投掷TaskCanceledException?
是.添加一个空的延续:
var delayTask = Task.Delay(1000, cancellationToken);
var continuationTask = delayTask.ContinueWith(task => { });
await continuationTask;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3206 次 |
| 最近记录: |