等待任务并静默停止取消或失败

时间:2015-12-01 14:39:39

标签: c# .net task

我想写的是:

async void Foo()
{
    var result = await GetMyTask().IgnoreCancelAndFailure();
    ProcessResult(result);
}

而不是:

void Foo()
{
    GetMyTask().ContinueWith(task => ProcessResult(task.Result),
        TaskContinuationOptions.OnlyOnRanToCompletion);
}

但是我不知道如何实现IgnoreCancelAndFailure方法,它具有以下签名:

//On cancel or failure this task should simply stop and never complete.
Task<T> IgnoreCancelAndFailure<T>(this Task<T> task) 
{
     throw new NotImplementedException(); 
}

如果可能,我该如何实施IgnoreCancelAndFailure?

3 个答案:

答案 0 :(得分:5)

您可以执行类似的操作,但是您需要知道在失败的情况下您希望方法返回什么,因为需要返回值:

public static async Task<T> IgnoreCancelAndFailure<T>(this Task<T> task) 
{
     try
     {
         return await task;
     }
     catch
     {
         return ???; // whatever you want to return in this case
     }
}

如果它是一个没有结果的Task,只需将catch留空(或者记录异常...吞下异常以进行硬调试)

如果您只想在ProcessResult成功时执行GetMyTask,则可以执行以下操作:

async void Foo()
{
    try
    {
        var result = await GetMyTask();
        ProcessResult(result);
    }
    catch(Exception ex)
    {
        // handle the exception somehow, or ignore it (not recommended)
    }
}

答案 1 :(得分:0)

在终止线程或进程时,您永远无法阻止代码继续期望。请记住,await任务可以被视为一个函数调用,它总是必须返回一个值或抛出异常。 缩短代码的最接近的方法是创建一个使用ProcessResult方法作为Action参数的包装函数。 这样的事情:

public static async Task IgnoreCancelAndFailure<T>(this Task<T> task, Action<T> resultProcessor) 
{
    task.ContinueWith(t => resultProcessor(t.Result),
        TaskContinuationOptions.OnlyOnRanToCompletion);
}

async void Foo()
{
    GetMyTask().IgnoreCancelAndFailure(ProcessResult);
}

答案 2 :(得分:-1)

我想我找到了答案。以下似乎可以解决问题。它使用了等待模式。你能证实这不是邪恶的吗?

{{1}}