如何从Action <t>中捕获异常或在c#中包含匿名方法?

时间:2016-09-06 19:14:00

标签: c# exception lambda error-handling

我正在尝试创建一个与此类似的全局异常方法,因此我可以显示异常以及在异常之前可能已捕获的任何数据

public class ServiceResponse<T> {
   public T Data {get;set;}
   public List<Exception> Errors {get;set;}
}

public static ServiceResponse<T> GetServiceResponse<T>(this ServiceResponse<T> response, Action<T> action)  
    {
        try
        {
           action(response.Data);
        }
        catch (Exception ex)
        {
            if (response.Errors == null)
            {
                response.Errors = new List<Error>();
            }
            response.Errors.Add(ex);
        }
        return response;

    }

它将被称为:

await Task.WhenAll(myTask1, myTask2).ContinueWith(t =>{ /*this is needed */ });
var response = new ServiceResponse<myData>();
response = response.GetServiceResponse(async r =>
                {
                    var info= await myTask1;
                    r.Status= info.status;
                    r.Timeout = info.Timout;
                })
           .GetServiceResponse(async r => { r.Hybrid = await myTask2; });

问题是当Task1或Task2有异常时,它永远不会被GetServiceResponse方法中的catch捕获。

2 个答案:

答案 0 :(得分:4)

那是因为该方法不会抛出异常。它会返回Task,最终会以Faulted状态结束。

如果你想处理异步方法,你需要创建一个额外的方法重载,其中委托返回Task(另一个返回Task<T>),这样你就可以捕获方法抛出的任何异常,但也添加一个延续来处理生成的Task中存储的任何异常。

答案 1 :(得分:0)

我能够通过将任务作为单独的参数传递来捕获异常,然后检查 IsFaulted 属性:

public static ServiceResponse<T> GetServiceResponse<T, K>(this ServiceResponse<T> response, Action<T, Task<K>> action, Task<K> task) where T : class
    {
        try
        {
            if (!task.IsFaulted)
            {
                action(response.Data, task);

            }
            else
            {
                if (response.Errors == null)
                {
                    response.Errors = new List<Error>();
                }
                if (task.Exception != null && task.Exception.InnerException != null)
                {
                    throw task.Exception.InnerException;
                }
                throw new Exception("Faulted");

            }
        }
        catch (Exception ex)
        {
            if (response.Errors == null)
            {
                response.Errors = new List<Exception>();
            }
            Debug.WriteLine(ex.Message);
            response.Errors.Add(ex);
        }
        return response;

    }