从Task.run到正确等待和调试器的例外



这是抛出异常的任务。

public Task<SensorReading> ReadSensorsAsync(int cell)
{
    return Task.Run(() => {
            throw new ArgumentNullException();
...

这是async方法:

private async void TimerCallback(object state)
{
    try
    {
        var tasksRead = Enumerable.Range(3, 35).Select(i => sensorReader.ReadSensorsAsync(i)).ToList();
        await Task.WhenAll(tasksRead);
        var r = tasksRead.Select(x => x.Result).ToList();
        var taskRecordREsult = RecordReadingAsync(r).Result;
    }
    catch(Exception e)
    {
        // expecting to catch everything here
    }
}

我期望的是,在代码的await部分中将处理例外。但是,在Visual Studio调试器中,我没有例外。

问题 - 如何将所有类型的例外从Task.Run正确地传递到等待部分?

一种可能的解决方案是将您的任务提取到独立方法中,然后将[DebuggerStepThrough]属性添加到它。从理论上讲(我尚未对此进行测试),这将抑制调试器中的第一个例外,并允许以后将其捕获。它不是很漂亮,但是应该解决问题。

尝试此程序,看看您是否仍然会破裂。

它为我工作

class Program
{
    static void Main(string[] args)
    {
        new Program().TimerCallback();
    }
    public Task<string> ReadSensorsAsync(string cell)
    {
        return Task.Run(() =>
        {
            if(cell == null) throw new ArgumentNullException();
            return cell;
        });
    }
    public Task<string> RecordReadingAsync(IEnumerable<string> cell)
    {
        return Task.Run(() =>
        {
            return string.Join(",", cell);
        });
    }
    public async void TimerCallback()
    {
        try
        {
            var tasksRead = new string[] { "1", null, "3" }.Select(s => ReadSensorsAsync(s));
            var taskRecordResult = await RecordReadingAsync(await Task.WhenAll(tasksRead));
            Debugger.Log(1, "test", taskRecordResult);
        }
        catch (Exception e)
        {
            //catches here
            Debugger.Log(1, "test", e.Message ?? e.ToString());
        }
    }
}

最新更新