简体   繁体   中英

Where could an UnobservedTaskException be occurring?

I have a WPF client that accesses a WCF service. The service runs along very nicely using a timer to execute some processing every n minutes. The client UI has a ProcessNow command, which overrides the service's timer, and performs the processing immediately. I am trying to sort out a usability problem where clicking the Process Now button more than once, while processing is still busy, results in a "connection closed" exception, from the WCF comms channel I assume, followed by a UnobservedTaskException .

The exception message explains that its cause is either not waiting on the task, or not accessing its Exception property. I only have two apparent uses of a Task anywhere in my solution, and one is in my view model:

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

The other is in a small utility method in the same viewmodel:

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);
    }
}

In the first code excerpt, I do seem to be waiting on the task, but I am more suspicious of the second, based on an example I found somewhere online. I use that to try and perform non-blocking checks like:

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

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

The last piece of code is called in my WCF client when I try and keep my command button updated with:

ProcessNow.RaiseCanExecuteChanged();

I am very new to both async and WCF, so please excuse any obvious blunders here.

ExecuteProcessNowCommand will not cause this. If an unhandled exception is thrown in async void method, process is taken down. So that's not the case.

Only thing left is ExecuteWithTimeout . Yes it can cause result in UnObservedTaskException if unhandled exception is thrown in the timedTask .

You're waiting on it, waiting should observe the exception, but you're waiting with a Timeout. If the exception is thrown after the Timeout has been passed, you'll see this behavior.

You need to attach continuation to the timedTask and observe the exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM