C# 如何使用WCF修复WPF中损坏的服务并返回数据?

C# 如何使用WCF修复WPF中损坏的服务并返回数据?,c#,.net,wpf,wcf,C#,.net,Wpf,Wcf,我有一个WPF应用程序,在该应用程序中,当用户调用它时,我希望返回数据列表或任何数据。我还需要调用WCF服务来获取数据。如果服务因任何原因而关闭,并且我希望修复损坏的服务或等待服务处于活动状态并返回数据,该怎么办。让我告诉你我在做什么: public List<MyData> GetMyData() { try { var data =GetOrCreateChannel().GetMyDat

我有一个WPF应用程序,在该应用程序中,当用户调用它时,我希望返回数据列表或任何数据。我还需要调用WCF服务来获取数据。如果服务因任何原因而关闭,并且我希望修复损坏的服务或等待服务处于活动状态并返回数据,该怎么办。让我告诉你我在做什么:

    public List<MyData> GetMyData()
    {
           try
           {
               var  data =GetOrCreateChannel().GetMyData(); //GetOrCreateChannel method create WCF service channel
              return data;
           }
           catch(Exception ex)
           {
               _log.error(ex);
                FixedBrokenService()
                return GetMyData(); //Call again this method.
           }
    }
公共列表GetMyData()
{
尝试
{
var data=GetOrCreateChannel().GetMyData();//GetOrCreateChannel方法创建WCF服务通道
返回数据;
}
捕获(例外情况除外)
{
_日志错误(ex);
FixedBrokenService()
return GetMyData();//再次调用此方法。
}
}

在上面的方法中,若服务并没有运行,它将转到catch块并再次调用相同的方法,直到服务关闭为止。每当服务处于活动状态时,它都将返回数据。我想知道这种方法是好是坏?若服务停止2到3小时,它将递归调用方法,内存中的堆栈大小将增加。还有别的办法吗

尝试将wcf客户端与ClientBase一起使用(有很多示例)。您可以注册到名为InnerChannel.Faulted的InnerChannel事件。当调用该事件时,表示服务以某种方式失败

相反,如果立即尝试在catch中连接,则可以编写一个单独的线程,在服务停止时重试与客户端连接

若服务停止2到3小时,它将递归调用方法,内存中的堆栈大小将增加。还有别的办法吗

我认为你这样问是因为你已经意识到可能有其他方法来改进你目前所拥有的东西;我猜你在寻找一些标准。

如果是这样的话,我推荐谷歌的指数退避指南,适用于谷歌地图通话。

其思想是在对web服务的后续调用之间引入一个延迟在反复失败的情况下增加它

一个简单的改变是:

public List<MyData> GetMyData()
{
    List<MyData> data = null;
    int delayMilliseconds = 100;
    bool waitingForResults = true;

    while (waitingForResults)
    {
        try
        {
            data = GetOrCreateChannel().GetMyData();

            waitingForResults = false; // if this executes, you've got your data and can exit
        }
        catch (Exception ex)
        {
            _log.error(ex);
            FixedBrokenService();

            Thread.Sleep(delayMilliseconds); // wait before retrying
            delayMilliseconds = delayMilliseconds * 2; // increase your delay
        }
    }
    return data;
}

这看起来像是一场恶梦。那么,
FixMyBrokenService
会做什么呢?它会重新创建通道,这不也是递归调用会做的吗?这两个都是个坏主意。GetOrCreate仅返回chanel对象。和fix方法修复通道。好的,但如果服务处于活动状态,我如何将getdata结果返回给调用方法呢?就像您在示例中所做的,但使用客户端。返回serviceClient.GetData()
private async static Task Wait(int delayMilliseconds)
{
    await WaitAsync(delayMilliseconds);
}

private static Task WaitAsync(int delayMilliseconds)
{
    Thread.Sleep(delayMilliseconds);
    return new Task(() => { });
}