【发布时间】:2018-04-01 17:07:22
【问题描述】:
我的代码调用了当前未运行的 WCF 服务。所以我们应该期待EndPointNotFoundException。 using 语句尝试Close() 导致出现异常的CommunicationObjectFaultedException 的连接。此异常在 using 块周围的 try catch 块中被捕获:
class Program
{
static void Main()
{
try
{
using (ChannelFactory<IDummyService> unexistingSvc = new ChannelFactory<IDummyService>(new NetNamedPipeBinding(), "net.pipe://localhost/UnexistingService-" + Guid.NewGuid().ToString()))
{
using (IClientChannel chan = (unexistingSvc.CreateChannel() as IClientChannel))
{
(chan as IDummyService)?.Echo("Hello");
}
}
}
catch (EndpointNotFoundException ex)
{
Console.WriteLine("Expected");
}
catch (CommunicationObjectFaultedException ex)
{
Console.WriteLine("Expected: caused by closing channel that has thrown EndPointNotFoundException");
}
}
}
请注意,服务 EndPoint 使用新的 Guid,因此它永远不会有服务监听。
IDummyService 是:
[ServiceContract]
interface IDummyService
{
[OperationContract]
string Echo(string e);
}
这会导致 Visual Studio 调试器 (Visual Studio Professional 2017 15.4.1) 中断并出现“异常未处理”弹出窗口:
Visual Studio 中断的异常是 System.ServiceModel.CommunicationObjectFaultedException,被捕获在代码中。
单步继续执行表明已到达catch(CommunicationObjectFaultedException ex)。使用 LinqPad 运行演示也表明异常被按预期捕获。
我还尝试显式(双重)关闭通道而不是使用using-block:
class Program
{
static void Main()
{
try
{
using (ChannelFactory<IDummyService> unexistingSvc = new ChannelFactory<IDummyService>(new NetNamedPipeBinding(), "net.pipe://localhost/UnexistingService-" + Guid.NewGuid().ToString()))
{
IDummyService chan = null;
try
{
chan = unexistingSvc.CreateChannel();
chan.Echo("Hello");
}
catch (EndpointNotFoundException ex)
{
Console.WriteLine($"Expected: {ex.Message}");
}
finally
{
try
{
(chan as IClientChannel)?.Close();
}
catch (CommunicationObjectFaultedException ex)
{
Console.WriteLine($"Caused by Close: {ex.Message}");
}
}
}
}
catch (EndpointNotFoundException ex)
{
Console.WriteLine("Expected");
}
catch (CommunicationObjectFaultedException ex)
{
Console.WriteLine("Expected: caused by closing channel that has thrown EndPointNotFoundException");
}
}
}
这仍然会导致调试器在 Close 语句上中断。
我的异常设置未选中 System.ServiceModel.CommunicationObjectFaultedException。 (当它被选中时,Visual Studio 会按预期中断并使用“抛出异常”对话框而不是“异常未处理”对话框)。
当我启用“选项”\“调试”\“常规”\“启用我的代码”时,调试器不会中断。但是,我有 async 方法,异常应该离开我的代码,后来我在 awaiting Task 时捕获了异常。对于这些方法,我需要取消选中“仅启用我的代码”;见Stop visual studio from breaking on exception in Tasks。
禁用“使用新的异常帮助程序”(如 Jack Zhai-MSFT 所建议的那样)Visual Studio 仍然中断并显示 该对话框提供了一些附加信息:
异常在跨越托管/原生边界之前未被捕获。
我怀疑 using 块可能引入了这个托管/本机边界。
是什么导致调试器错误中断以及如何使调试器既不中断也不处理CommunicationObjectFaultedExceptions 或以后的处理程序async 异常?
【问题讨论】:
-
如果在VS2017中禁用TOOLS->OPTION->Debugging->General下的调试选项“Use the New Exception Helper”,结果如何?
-
@JackZhai-MSFT 我在禁用“使用新的异常帮助程序”的情况下进行了测试,并将结果包含在问题中。旧的异常对话为尝试解决问题提供了一些新途径。
-
@JackZhai-MSFT 谢谢,您的建议帮助我通过正确的设置解决了问题。现在发布答案。
-
很高兴知道它对您有帮助,我将其添加为有用的答案,当然,如果您有其他有用的信息来补充它,您可以编辑该答案。祝你有美好的一天:)
标签: c# visual-studio debugging unhandled-exception