【问题标题】:Proper Error Handling on a WCF service call正确处理 WCF 服务调用的错误
【发布时间】:2010-11-16 21:55:14
【问题描述】:

我很想找出最好的方法来调用 WCF 服务并在发生错误或超时时处理它。这是我正在做的事情:

我有一个这样的数据服务接口:

public interface IDataService

{ void GetUserId(string userName, string password, Action getUserIdComplete); }

我是这样实现的:

public class MockDataService : IDataService
{
    private Action<string> _getUserIdCompleted;
    private SomeServiceClient;

    public MockDataService()
    {
        _proxy = new SomeServiceClient();
    }

    public void GetUserId(string userName, string password, Action<int> getUserIdComplete)
    {
        _getUserComplete = getUserIdComplete;

        var request = new UserRequest();
        request.UserName = userName;
        request.Password = password;
        //populate any other request info

        _proxy.GetUserIdCompleted += new EventHandler<GetUserCompletedEventArgs>(_proxy_GetUserIdCompleted);
        _proxy.GetUserIdAsync(request);
    }

    void _proxy_GetUserIdCompleted(object sender, GetUserIdCompletedEventArgs e)
    {
        _proxy.GetUserIdCompleted -= new EventHandler<GetUserCompletedEventArgs>(_proxy_GetUserIdCompleted);
        _getUserIdComplete(e.UserId);
    }
}

我的问题是,当发生错误或请求超时时,应用程序将终止。我可以在调用周围包裹一个 try catch 块,但这听起来是个坏主意。

有人可以帮我用这种方法优雅地处理超时和错误吗?

【问题讨论】:

    标签: c# silverlight wcf design-patterns


    【解决方案1】:

    据我所知,捕获超时异常是处理它的唯一方法。

    我更喜欢使用另一种异步模式,因为它可以更灵活地处理异常。我会去这样的。

    public class MockDataService : IDataService
    {
        private SomeServiceChannel _channel;
    
        public MockDataService()
        {
            var channelFactory = new ChannelFactory<SomeServiceChannel>(
                        "CustomBinding_SomeService");
            _channel = channelFactory.CreateChannel();
            //to increase the timeout
            _channel.OperationTimeout = TimeSpan.FromMinutes(5);
        }
    
        public void GetUserId(string userName, string password, Action<int> getUserIdComplete)
        {
            var request = new UserRequest();
            request.UserName = userName;
            request.Password = password;
            //populate any other request info
    
            _proxy.GetUserIdCompleted += new EventHandler<GetUserCompletedEventArgs>(_proxy_GetUserIdCompleted);
            _proxy.GetUserIdAsync(request);
            _channel.BeginGetUserId(request, (iar) =>
               {
                   try
                   {
                       var result = _channel.EndGetUserId(iar);
                       getUserIdComplete(result.UserId);
                   }
                   catch (Exception ex)
                   {
                       //handle the exception
                   }
               }, null);
        }
    
    }
    

    【讨论】:

    • 哇,我非常喜欢这个!感谢您的建议。我会试试这个。我实际上并没有看到太多好的异步模式,但我确实喜欢这个。
    【解决方案2】:

    以我的拙见,后台线程上的回调(任何由异步执行产生的)应该始终包装在异常处理程序中。后台线程中未处理的异常杀死你的进程。

    现在,这并不意味着您应该捕获异常并忽略它:) 只是您应该正确处理它,无论这对您的应用程序意味着什么。对于某些将记录它们的应用程序。对于其他人,它将在某处更新某些状态。对于其他人,它可能会提醒用户错误。或者它们的组合:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-13
      • 2015-01-14
      • 2014-02-10
      相关资源
      最近更新 更多