0

I am consuming a WCF service using an event-based proxy generated by Visual Studio. I have run into an issue, where my application will hang if the call to the service times out. The call to the service is as follows:

ServiceClient client = new ServiceClient(binding, endpointAddress);
client.AuthenticateCompleted += (sender, e) =>
{
    if (e.Error != null)
        throw e.Error;
};
client.AuthenticateAsync(username, password);

Browsing through countless other questions, the general consensus is that any exceptions should be caught by WCF and found in e.Error above. However, when my service times out, this is not the case, the error is either null, or in some other tests I've run, the app has crashed before reaching this point in the code. Another user suggested wrapping the above code in a try/catch block, however, doing this also fails to catch the exception.

I have also tried placing try/catch blocks inside the completion handler, as well as numerous other more complicated methods which are beyond the scope of the question, as I really just need this working in its simplest form to continue.

It may also be worth mentioning that while many of these failures occurred on the live service with a open, close, send, and receive timeout of 30 seconds each, I have also been attempting to test fixes to the issue by bringing the timeout down to <1 second. I presume this would still be generating Timeout Exceptions and not causing any other issues, but I'm not 100% sure.

I also did not create the WCF service, so if something specific needs to be done on the server side to throw exceptions back to the client, it is possible this element is missing. If this is the case, is there any way around this?

4

1 回答 1

0

事实证明,错误是由IService.EndMethodName无法通过 Visual Studio 生成的类访问的方法引发的。

相反,我决定直接访问频道,这样我就可以更好地控制事情了。最终实现如下所示(IService 是 Visual Studio 生成的接口):

ChannelFactory<IService> factory = new ChannelFactory<IService>(binding, endpointAddress);

// CreateChannel may not require any parameters outside of Mono
IService channel = factory.CreateChannel(endpointAddress);

channel.BeginAuthenticate(new AuthenticateRequest(arg0, arg1), result =>
{
    try
    {
        channel.EndAuthenticate(result);
    }
    catch(Exception ex)
    {
        throw;
    }
}, channel);

这是最简单的形式,但总体思路是调用在AsyncCallbacktry/catch 块内结束,以便在那里进行任何异常处理。

于 2017-07-09T01:41:46.490 回答