Реализация конвеера на технологии WCF

127
01 сентября 2019, 13:10

Есть следующая задача: Реализовать WCF сервис (внутри сервиса крутятся несколько обобщенных очередей в которые помещаются типизированные объекты Call - посредсвом обращения к сервису, у каждого объекта Call есть метод Execute делающий запрос к внешнему API и возвращает в виде колбека ответ).

реализация конракта

public class EDA : IEDA
    {
        private static List<ExchangeCallbackMessage> callbackMessages = new List<ExchangeCallbackMessage>();
        private readonly Middlewaire<PoloExchange> poloPipeline = new Middlewaire<PoloExchange>(Configs.GetApiToken("polo"));
        //public EDA()
        //{
        //    callbackMessages = new List<ExchangeCallbackMessage>();
        //    poloPipeline = new Middlewaire<PoloExchange>(Configs.GetApiToken("polo"));
        //}
        public async Task<string> ReturnAddressAsync(string exchangeId, string currencyId)
        {
            poloPipeline.Callback += ExchangeMessageReceiver;
            var callParams  = new CallParams(currId : currencyId);
            if (exchangeId == "polo")
            {
                var addressCall = new CallGetAddress<PoloExchange>(ref callParams);
                await poloPipeline.AddCallAsync(addressCall);
            }
            return callbackMessages.FirstOrDefault(m => m.CallId == callParams.CallId).Address;
        }
        private static void ExchangeMessageReceiver(ExchangeCallbackMessage message)
        {
            callbackMessages.Add(message);
        }
    }

реализация очереди

public class Middlewaire<T> where T : class, IExchange, new()
    {
        internal readonly T exchangeClient;
        private Queue<Call<T>> Processor { get; set; }
        public event ExchangeHandler Callback;
        public void CallbackAction(ExchangeCallbackMessage callbackMessage) 
            => Callback?.Invoke(callbackMessage);
        public Middlewaire(ApiToken credential)
        {
            exchangeClient = new T();
            exchangeClient.Initialize(credential);
            Processor = new Queue<Call<T>>();
            var tm = new TimerCallback(TactAction);
            var timer = new Timer(tm, new object(), 0, 167);
        }
        public void TactAction(object obj)
        {
            //var processor = obj as Queue<Call<T>>;
            while (true)
            {
                if (Processor.Count != 0)
                {
                    CallbackAction(Processor.Dequeue().Execute(exchangeClient));
                }
                else continue;
            }
        }
        public async Task AddCallAsync(Call<T> call) => await Task.Run(() => Processor.Enqueue(call));
    }

Очередность действий следующа:

  1. Внешнее приложение дергает нужный конракт и передает в него некий набор данных(две строки).
  2. На основе этих строк создаем типизированный Call, выберам нужную очередь и помещаем в нее Call.
  3. Очередь во время очередного такта вызывает метод Execute объекта Call, делающий запрос к внешнему АПИ.
  4. АПИ отдает ответ, который в виде колбека, возвращает его в контракт, где он в свою очередь обрабатывается и отправляется внешнему приложению.

Сервис запускается и стабильно работает но когда я хочу дернуть за контрак - он не исполняется. Во время дебага вижу что поток исполнения заново создает очередь заходит в цикл и крутится там пока не выдаст ошибку таймаута:

System.AggregateException
  HResult=0x80131500
  Message=One or more errors occurred. (The request channel timed out attempting to send after 00:01:00. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout.)
  Source=System.Private.CoreLib
  StackTrace:
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at EdaCoreTest.Program.GetRestr(EDAClient client) in D:\Work Folder\Test_C#_project\EdaCoreTest\EdaCoreTest\Program.cs:line 29
   at EdaCoreTest.Program.Main(String[] args) in D:\Work Folder\Test_C#_project\EdaCoreTest\EdaCoreTest\Program.cs:line 14
Inner Exception 1:
TimeoutException: The request channel timed out attempting to send after 00:01:00. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout.
Inner Exception 2:
TimeoutException: The HTTP request to 'http://localhost:58995/EDA.svc' has exceeded the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout.

Возможно я не до конца понимаю технологию WCF, или же какието ошибки в архтектуре или може еще что-то. В общем уповаю на независимую оценку ситуации со стороны.

READ ALSO
Добавление данных в DataGrid в wpf

Добавление данных в DataGrid в wpf

Прошу помочь в следующем вопросе: У меня есть метод, который делает десериализацию данных, после десериализации данные добавляются в список...

112
Блокируется UI при работе с другим окном

Блокируется UI при работе с другим окном

Переделал код под async await, и всё работает замечательно, до тех пор, пока не начинаю работать с другим окномВ этом случае UI главного окна блокируется

123
Передать объект из JS в PHP?

Передать объект из JS в PHP?

Как передать объект почему не получается? Что я не так делаю? JS:

124