C# 哪里会发生未观察到的异常情况?
我有一个访问WCF服务的WPF客户端。该服务运行得很好,使用计时器每n分钟执行一次处理。客户端UI有一个C# 哪里会发生未观察到的异常情况?,c#,wpf,wcf,async-await,C#,Wpf,Wcf,Async Await,我有一个访问WCF服务的WPF客户端。该服务运行得很好,使用计时器每n分钟执行一次处理。客户端UI有一个ProcessNow命令,该命令覆盖服务的计时器,并立即执行处理。我正在试图解决一个可用性问题,即在处理仍然繁忙的情况下,多次单击“立即处理”按钮会导致“连接关闭”异常,我假设是来自WCF通信通道,然后是一个“未观察到的异常” 异常消息说明其原因不是没有等待任务,就是没有访问其异常属性。在我的解决方案中,我的任务有两个明显的用途,一个是在我的视图模型中: async void ExecuteP
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
,然后在其中放置一个断点,并查看异常
或异常
属性以查看导致失败的原因。@YuvalItzchakovExecuteProcessNowCommand()
在我单击绑定到命令的“立即处理”按钮时由WPF调用。“我没有明确地称之为任何地方。”史蒂夫米查姆,谢谢你。我把catch
块从我的摘录中删除了,我也没有注意到它。我只捕获了WCF所期望的FaultException
,当我无法使其工作时,我放弃了WCF。它实际上不是异步void
。我没有声明任何异步方法,但WCF代理生成器会声明。当我尝试抛出一个FaultException
时,我在某个地方读到async void会关闭进程,所以我让process
返回int
。现在,生成的ProcessAsync
返回Task
。不过,我要先仔细看看timedTask
。您所说的似乎符合这种情况。@ProfK我相信当抛出UnobservedTaskeException
时,您可以检查InnerException
属性以查找有关原始异常发生位置的更多信息。那应该对你有帮助