Есть следующая задача:
Реализовать 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));
}
Очередность действий следующа:
Call
, выберам нужную очередь и помещаем в нее Call
.Execute
объекта Call
, делающий запрос к внешнему АПИ.Сервис запускается и стабильно работает но когда я хочу дернуть за контрак - он не исполняется. Во время дебага вижу что поток исполнения заново создает очередь заходит в цикл и крутится там пока не выдаст ошибку таймаута:
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, или же какието ошибки в архтектуре или може еще что-то. В общем уповаю на независимую оценку ситуации со стороны.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Прошу помочь в следующем вопросе: У меня есть метод, который делает десериализацию данных, после десериализации данные добавляются в список...
Переделал код под async await, и всё работает замечательно, до тех пор, пока не начинаю работать с другим окномВ этом случае UI главного окна блокируется