2016-02-12 239 views
0

让我们假设我有WCF服务和一个客户端,它使用给定服务中的某些方法。 在客户和服务交流期间,如何处理各种异常的帖子有很多。只有这仍然是困惑我的事情是以下情况:如何处理WCF连接失败

服务:

[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    bool ExportData(object data); 
} 
public class Service1 : IService1 
{ 
    public bool ExportData(object data) 
    { 
     // Simulate long operation (i.e. inserting data to the DB) 
     Thread.Sleep(1000000); 
     return true; 
    } 
} 

客户:

class Program 
{ 
    static wsService1.Service1Client client1 = new wsService1.Service1Client(); 

    static void Main(string[] args) 
    { 
     object data = GetRecordsFromLocalDB(); 

     bool result = client1.ExportData(data); 

     if (result) 
     { 
      DeleteRecordsFromLocalDB(); 
     } 
    } 
} 

客户从本地数据库得到了一些数据,并将其发送给服务器。如果结果成功,则客户端将从本地数据库中删除导出的行。现在想象一下,当数据已经发送到服务器时,突然连接失败(即WiFi被断开)。在这种情况下,数据在服务器端成功处理,但客户端永远不知道它。是的,我可以捕捉连接异常,但我仍然不知道该如何处理本地数据库中的记录。我稍后可以再次发送这些数据,但是我会在服务器数据库上重复一次(即在远程数据库上允许复制),但我不想多次发送相同的数据。

那么,我的问题是如何处理这种情况?什么是最佳实践? 我查了一些关于asynchronous operations.的信息但是这仍然是关于什么时候我有稳定的连接。 作为解决方法,我可以将我的导出操作存储在某个GUID的remotelly下,并稍后检查此GUID的状态。唯一的事情是我无法更改远程数据库。所以,请说明一下,在我的情况下哪个更好?

回答

1

这里有几点需要考虑

  1. 在服务器端你可以捕捉各种错误的(定制类派生IErrorHandler)和客户提供特定的错误让他知道错误的原因。
  2. 服务的概念是它是客户端和数据库之间的一种中介,所以客户端为什么要检索数据然后发送给服务?
  3. 一个出路是使用交易,确保如果发生错误,则不会保留更改。

顺便说一句,如果您希望服务抛出异常,请不要创建全局服务对象,因为它最终会处于故障状态。改为为每一个调用创建一个新实例(使用using语句来处理它的实例)。 Bool返回类型不提供有关错误的广泛信息(如果发生的话)。让它具有void返回类型并在try/catch块中进行换行,以便更多地了解错误的来源和性质。

+0

通常,WCF服务会在'FaultException'中返回异常详细信息,而不是向客户端暴露全局'IErrorHandler'对象(如果服务器关闭,它们将无法到达)。 https://msdn.microsoft.com/en-au/library/ee942778.aspx – MickyD