Влияет ли сигнализация ManualResetEventSlim на производительность? - PullRequest
1 голос
/ 28 апреля 2020

Я использую ManualResetEventSlim, чтобы иметь механизм сигнализации в моем приложении, и он прекрасно работает, если количество запросов / se c равно 100. Когда я увеличиваю количество запросов / se c, оно ухудшается.

Пример:

100 запросов / se c -> 90% транзакций, выполненных за 250 мс, а пропускная способность (успешный запрос / se c) составляет 134.

150 запросов / se c - > 90% транзакций выполнено за 34067 мс, а пропускная способность (успешный запрос / se c) составляет 2,2.

Я использую ConcurrentDictionary, как указано ниже:

// <key, (responseString,ManualResetEventSlim) >
private static ConcurrentDictionary<string, (string, ManualResetEventSlim)> EventsDict = new ConcurrentDictionary<string, (string, ManualResetEventSlim)>();

Ниже данный процесс описывает необходимость в ManualResetEventSlim ( Api Solution 1 и Api Solution 2 полностью:

  1. Api Solution 1 (REST Api) получено запрос, он добавил элемент (null, ManualResetEventSlim) в ConcurrentDictionary против ключ и вызвал службу третьих сторон (SOAP), используя async / await. Thirdparty soap api вернул ответ подтверждения, но фактический ответ находится на рассмотрении После получения подтверждения Элемент ответа отправляется на ManualResetEventSlim.wait

  2. Как только третья сторона обработает запрос, она вызывает Api Solution 2 (SOAP) с использованием открытого метода и отправляет фактический ответ , Api решение 2 отправляет ответ на Api Solution 1 (REST Api) , отправляя запрос http, а затем вставляет данные в базу данных для аудита.

  3. Api Solution 1 получит ключ из строки ответа и обновит строку ответа в ConcurrentDictionary и установит сигнал.

  4. Api Solution 1 располагает объект ManualResetEventSlim перед возвратом ответа клиенту.

1 Ответ

1 голос
/ 28 апреля 2020

Я думаю, вы должны быть в состоянии избавиться от кода блокировки, заменив (string, ManualResetEventSlim) на TaskCompletionSource<string>:

В решении 1 вы могли бы сделать что-то подобное:

TaskCompletionSource<string> tcs = new TaskCompletionSource<string>()
EventsDict.AddOrUpdate( key, tcs );
await KickOffSolution2ThirdParty( /*...*/ );
string result = await tcs.Task; // <-- now not blocking any thread anymore

И аналог:

void CallbackFromSolution2( string key, string result )
{
     if( EventsDict.TryRemove(key, out TaskCompletionSource<string> tcs )
     {
         tcs.SetResult(result);
     }
}

Это, конечно, только грубая схема идеи. Но, надеюсь, достаточно, чтобы сделать мой ход мысли понятным. Я не могу проверить это прямо сейчас, поэтому любые улучшения / исправления приветствуются.

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