Я пытаюсь использовать TPL в сервисе windows для эффективной асинхронной обработки. Служба работает бесконечно l oop, пока служба не будет отменена.
Вот код, который я использую для основных методов службы:
private CancellationTokenSource cancellationTokenSource;
private readonly List<Task> tasks = new List<Task>();
protected override void OnStart(string[] args)
{
cancellationTokenSource = new CancellationTokenSource();
tasks.Add(Task.Factory.StartNew(() =>
{
Worker(cancellationTokenSource.Token);
}, cancellationTokenSource.Token));
}
private async void Worker(CancellationToken token)
{
bool keepGoing = true;
while (keepGoing)
{
try
{
if (token.IsCancellationRequested)
{
token.ThrowIfCancellationRequested();
}
//Parallel.ForEach(processors, processor =>
//{
await processor.Process();
//});
}
catch (Exception ex)
{
if (ex is OperationCanceledException)
{
keepGoing = false;
}
else
{
//write log here
}
}
finally
{
await Task.Delay(configurationSettings.OperationSettings.ServiceOperationDelay, token).ContinueWith(tsk => { });
}
}
}
protected override void OnStop()
{
cancellationTokenSource.Cancel();
using var mres = new ManualResetEventSlim();
using (cancellationTokenSource.Token.Register(() => mres.Set()))
{
Task.Factory.ContinueWhenAll(tasks.ToArray(), (t) => mres.Set());
mres.Wait();
}
}
Вызов процессор в основном делает следующее:
var records = await interfaceService.Get()
foreach record retrieved
await interfaceService.Patch()
Служба использует экземпляр HttpClient для выполнения запросов.
**Get:**
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get,
"");
using HttpResponseMessage response = await httpClient.SendAsync(request);
if (response.IsSuccessStatusCode)
{
//return results
}
else
{
throw Exception("Foo bar")
}
**Patch**
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Patch, "")
{
Content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json")
};
using HttpResponseMessage response = await httpClient.SendAsync(request);
Проблема, с которой я сталкиваюсь, заключается в том, что если конечная точка становится недоступной, Служба просто не может эффективно отследить ни одно исключение или возвращенные ответы, и из-за отсутствия лучшей терминологии проваливается. Я полагаю, что моя проблема заключается в способе управления задачами.
В конечном итоге я хочу иметь службу с каждой итерацией l oop
- Выключить заданные c задачи асинхронно, которые выполняют операцию get / patch, сразу
- Подождите, пока все не будут завершены.
- Записать результаты каждой в файл
- Go для сна
- Запуск с шага # 1
Кроме того, когда служба останавливается, я хочу изящно остановить обработку каждой задачи.
Любая помощь в этом с благодарностью!