Как исправить сломанный Сервис и вернуть данные в WPF с WCF? - PullRequest
0 голосов
/ 08 января 2019

У меня есть приложение 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.
           }
    }

В приведенном выше методе, если служба не запущена, она переходит к перехвату блока и снова вызывает тот же метод до тех пор, пока служба не будет недоступна. Всякий раз, когда сервис оживает, он возвращает данные. Я хочу знать, подходит ли этот подход или нет? Что если сервис не работает в течение 2-3 часов, он рекурсивно вызовет метод, и размер стека в памяти увеличится. Есть ли другой подход?

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Что если сервис не работает в течение 2-3 часов, он рекурсивно вызовет метод, и размер стека в памяти увеличится. Есть ли другой подход?

Я думаю, вы спрашиваете, потому что вы уже чувствуете, что может быть какой-то другой способ улучшить то, что у вас есть; я думаю, вы ищете какой-то стандарт.

Если это так, я бы порекомендовал Google Показатель экспоненциального отката , здесь применительно к вызовам Google Maps.

Идея состоит в том, чтобы ввести задержку между последующими вызовами веб-службы, увеличить в случае повторных сбоев.

Простое изменение будет:

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;
}

Таким образом, вам также не придется иметь дело с рекурсией; не забудьте добавить using System.Threading; наверх.


Поскольку вы упомянули WPF, мы могли бы принять предложение Джероена и ждать в другом потоке : это означает, что ваш WPF GUI не будет заморожен , пока вы пытаетесь переподключиться, но это будет включен и, возможно, отображает счетчик, сообщение ожидания или что-то в этом роде (например, «Повторное подключение через x секунд»).

Это требует изменения второй строки на последнюю, то есть Thread.Sleep(delayMilliseconds); на Wait(delayMilliseconds); и добавления этих двух методов ниже GetMyData:

private async static Task Wait(int delayMilliseconds)
{
    await WaitAsync(delayMilliseconds);
}

private static Task WaitAsync(int delayMilliseconds)
{
    Thread.Sleep(delayMilliseconds);
    return new Task(() => { });
}
0 голосов
/ 08 января 2019

Попробуйте использовать клиент wcf с ClientBase (есть множество примеров). Вы можете зарегистрироваться на событие InnerChannel с именем InnerChannel.Fapted. Когда это событие вызывается, это означает, что служба как-то не сработала.

Вместо этого, если немедленно попытаться подключиться в перехватчике, вы можете написать отдельный поток, который попытается соединиться с клиентом, когда служба выйдет из строя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...