有没有办法在没有抛出异常的情况下等待TPL任务?

时间:2015-08-10 10:50:10

标签: c# .net exception-handling task-parallel-library

我们中的一些人更喜欢以异常轻量级的方式编写代码。但是,如果您等待任务并行库任务,并且任务引发了异常,它也会在调用线程上引发异常。是否有(最好是标准的)方法来避免这种行为,只是在你找回异常时检查异常的响应?

5 个答案:

答案 0 :(得分:12)

您可以使用Task.WaitAny:

        var task = Task.Run(() =>
        {
            // ...
            throw new Exception("Blah");
        });
        Task.WaitAny(task);
        if (task.IsFaulted)
        {
            var error = task.Exception;
            // ...
        }
        else if (task.IsCanceled)
        {
            // ...
        }
        else
        {
            // Success
        }

答案 1 :(得分:5)

不幸的是,此功能不是内置的。使用此解决方法:

 myTask.ContinueWith(_ => { }, TaskCOntonuationOptions.ExecuteSynchronously).Wait();

您可以将其转换为扩展方法。

答案 2 :(得分:5)

您不能在没有引发异常的情况下等待故障任务。 但是您可以等待继续执行该任务,该任务仅在原始任务完成后才完成,而不会引发异常:

struct sigaction

如果您的任务返回一个值,您可以在extensions方法中表示该值,如果没有例外则返回实际值,如果有,则返回默认值:

public static Task SwallowExceptions(this Task task)
{
    return task.ContinueWith(_ => { });
}

faultedTask.SwallowExceptions().Wait();
if (faultedTask.IsFaulted)
{
    // handle exception
}

答案 3 :(得分:2)

根据您所写的内容,可能会捕获异常并检查IsFaulted属性是您的解决方案吗? IsFaulted

答案 4 :(得分:1)

在Task中捕获异常并将其返回到结果中?

<p:scrollPanel mode="native" style="height: 200px;">
    <p:selectManyCheckbox id="groups" value="#{myBean.selectedGroups}" layout="custom" >
        <c:forEach items="#{myBean.myGroups}" var="group" >
            <f:selectItem itemValue="#{group.id}" itemLabel="#{group.name}"/>
        </c:forEach>
    </p:selectManyCheckbox>
</p:scrollPanel>