C# 哪里会发生未观察到的异常情况?

C# 哪里会发生未观察到的异常情况?,c#,wpf,wcf,async-await,C#,Wpf,Wcf,Async Await,我有一个访问WCF服务的WPF客户端。该服务运行得很好,使用计时器每n分钟执行一次处理。客户端UI有一个ProcessNow命令,该命令覆盖服务的计时器,并立即执行处理。我正在试图解决一个可用性问题,即在处理仍然繁忙的情况下,多次单击“立即处理”按钮会导致“连接关闭”异常,我假设是来自WCF通信通道,然后是一个“未观察到的异常” 异常消息说明其原因不是没有等待任务,就是没有访问其异常属性。在我的解决方案中,我的任务有两个明显的用途,一个是在我的视图模型中: async void ExecuteP

我有一个访问WCF服务的WPF客户端。该服务运行得很好,使用计时器每n分钟执行一次处理。客户端UI有一个
ProcessNow
命令,该命令覆盖服务的计时器,并立即执行处理。我正在试图解决一个可用性问题,即在处理仍然繁忙的情况下,多次单击“立即处理”按钮会导致“连接关闭”异常,我假设是来自WCF通信通道,然后是一个“未观察到的异常”

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

async void ExecuteProcessNowCommand()
{
        await _proxy.ProcessAsync(true);
}
另一个是同一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);
    }
}
在第一段代码摘录中,我似乎在等待任务,但根据我在网上找到的一个示例,我对第二段代码更加怀疑。我使用它尝试执行非阻塞检查,如:

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

            try
            {
                result = _proxy.CanUserForceProcessing();
            }
            catch (EndpointNotFoundException)
            {
                result = false;
            }
        });
    return result;
}
当我尝试使用以下命令更新命令按钮时,最后一段代码将在我的WCF客户端中调用:

ProcessNow.RaiseCanExecuteChanged();

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

ExecuteProcessNowCommand
不会导致这种情况。若在async void方法中抛出未处理的异常,则进程将被关闭。事实并非如此

只剩下
执行超时
。是,如果在
timedTask
中引发未经处理的异常,则可能导致
unobservedtaskeexception

您正在等待它,等待应该会观察到异常,但您正在等待一个超时。如果在超过超时后引发异常,您将看到此行为


您需要将continuation附加到
timedTask
并观察异常情况。

在代码中调用
ExecuteProcessNowCommand()
的位置?围绕第一个函数的内容添加异常处理程序,并捕获
aggregateeException
,然后在其中放置一个断点,并查看
异常
异常
属性以查看导致失败的原因。@YuvalItzchakov
ExecuteProcessNowCommand()
在我单击绑定到命令的“立即处理”按钮时由WPF调用。“我没有明确地称之为任何地方。”史蒂夫米查姆,谢谢你。我把
catch
块从我的摘录中删除了,我也没有注意到它。我只捕获了WCF所期望的
FaultException
,当我无法使其工作时,我放弃了WCF。它实际上不是
异步void
。我没有声明任何异步方法,但WCF代理生成器会声明。当我尝试抛出一个
FaultException
时,我在某个地方读到async void会关闭进程,所以我让
process
返回
int
。现在,生成的
ProcessAsync
返回
Task
。不过,我要先仔细看看
timedTask
。您所说的似乎符合这种情况。@ProfK我相信当抛出
UnobservedTaskeException
时,您可以检查
InnerException
属性以查找有关原始异常发生位置的更多信息。那应该对你有帮助