哪里可能发生UnobservedTaskException?

时间:2015-03-11 12:55:39

标签: c# wpf wcf async-await

我有一个访问WCF服务的WPF客户端。该服务运行非常好,使用计时器每n分钟执行一些处理。客户端UI具有ProcessNow命令,该命令将覆盖服务的计时器,并立即执行处理。我试图解决一个可用性问题,多次点击Process Now按钮,而处理仍然很忙,导致“连接关闭”异常,从我假设的WCF通信通道,然后是{{ 1}}。

异常消息说明其原因是要么没有等待任务,要么没有访问其UnobservedTaskException属性。在我的解决方案中,我只有两个Exception的明显用法,一个在我的视图模型中:

Task

另一个是在同一个视图模型中的小实用程序方法:

async void ExecuteProcessNowCommand()
{
        await _proxy.ProcessAsync(true);
}

在第一段代码摘录中,我似乎在等待任务,但我更加怀疑第二个,基于我在网上找到的一个例子。我用它来尝试执行非阻塞检查,如:

private void ExecuteWithTimeout(Action task, int? timeout = null)
{
    timeout = timeout ?? HostServiceConstants.ServiceControlTimeout;
    var source = new CancellationTokenSource();
    var timedTask = new Task(task, source.Token);
    timedTask.Start();
    bool done = timedTask.Wait(timeout.Value);
    if (!done)
    {
        source.Cancel();
        var frame = new StackFrame(1);
        var methodName = frame.GetMethod().Name;
        _logger.Warn("'{0}' timed out after {1} milliseconds.", methodName, timeout);
    }
}

当我尝试使用以下命令更新命令按钮时,在我的WCF客户端中调用最后一段代码:

bool CanExecuteProcessNowCommand()
{
    bool result = false;
    ExecuteWithTimeout(() =>
        {

            try
            {
                result = _proxy.CanUserForceProcessing();
            }
            catch (EndpointNotFoundException)
            {
                result = false;
            }
        });
    return result;
}

我对异步和WCF都很陌生,所以请原谅任何明显的错误。

1 个答案:

答案 0 :(得分:0)

ExecuteProcessNowCommand不会导致此问题。如果在异步void方法中抛出未处理的异常,则会关闭进程。事实并非如此。

只留下ExecuteWithTimeout。是的,如果在UnObservedTaskException中抛出未处理的异常,则可能导致timedTask的结果。

您正在等待它,等待应该观察异常,但您正在等待超时。如果在超时过后抛出异常,您将看到此行为。

您需要将延续附加到timedTask并观察异常。