【发布时间】:2017-06-26 03:36:03
【问题描述】:
我有一个任务是在套接字上循环读取:
private async void readLoop() {
while (!cts.IsCancelRequested()) {
await socket.ReceiveAsync(data, ...);
doWork(data);
}
}
由于任务不需要在创建后立即运行,因此我使用Task 构造函数,而不是Task.Run。
private Task readTask = new Task(readLoop, cts, LongRunning);
// when the task need to run:
readTask.Start()
此时它工作正常,除了当任务需要完成时,当我调用readTask.Wait() 或await readTask 时,ReceiveAsync 或doWork 中发生的异常未附加到readTask。这意味着即使有例外,readTask.Status 是 RunToComplete 和 readTask.Exception 是 null。符合。对于文档,这是由于异步方法返回 void,但是当我尝试这样做时:
private async Task readLoop() {...}
它不会编译:
error CS0407: 'Task WebSocketInitiator.readLoop()' has the wrong return type
那么有没有办法让任务在以后开始,同时让它跟踪任务中发生的异常?
显示问题的最小测试用例:https://dotnetfiddle.net/JIfDIn
【问题讨论】:
-
这里的底线:您的
async方法返回void,这会阻止任何调用代码观察异常,因为没有Task可以表示异常的方法。在这种情况下,您不应该使用async void,并且如果您遵循不这样做的推荐做法,您的问题就不会发生。为什么在更改返回类型时会得到 CS0407 我不能说;你肯定在其他地方也犯了错误,但你没有提供一个好的minimal reproducible example 可靠地重现问题,所以这个问题是什么,没有人能说。 -
@PeterDuniho 它不会编译,因为 Task() 需要 Action 作为它的第一个参数,而 action 只是 void foo(void);它不会接受任务 foo();
标签: c# asynchronous async-await task-parallel-library .net-core