Как повысить производительность айн c? - PullRequest
0 голосов
/ 06 мая 2020

Я работаю над проблемой, когда мне нужно удалить записи с помощью вызова службы. Проблема в том, что у меня есть a для каждого l oop, где у меня есть несколько операций ожидания. Из-за этого операция занимает много времени, а производительность отсутствует

foreach(var a in list<long>b)
    {
     await _serviceresolver().DeleteOperationAsync(id,a)
    }

Ответы [ 4 ]

1 голос
/ 07 мая 2020

Проблема в том, что у меня есть для каждого l oop, где у меня есть несколько операций ожидания. Это приводит к тому, что операция занимает много времени, а производительность снижается.

Решение номер один - уменьшить количество вызовов. Это часто называют «коренастым», а не «болтливым». Итак, если ваша служба поддерживает какую-либо операцию массового удаления, то выставьте ее в своем типе службы, а затем вы можете просто сделать:

await _serviceresolver().BulkDeleteOperationAsync(id, b);

Но если это невозможно, вы можете хотя бы использовать асинхронный параллелизм. Это сильно отличается от параллелизма; вы не хотите использовать Parallel или PLINQ.

var service = _serviceresolver();
var tasks = b.Select(a => service.DeleteOperationAsync(id, a)).ToList();
await Task.WhenAll(tasks);
0 голосов
/ 06 мая 2020

Вы ждете, пока каждая операция asyn c завершится sh прямо сейчас. Если вы можете уволить их всех одновременно, вы можете просто позвонить им без await, или, если вам нужно знать, когда они закончат sh, вы можете просто уволить их всех, а затем подождать, пока они все закончат sh отслеживая задачи в списке:

List<Task> tasks = new List<Task>();

foreach (var a in List<long> b)
    tasks.Add(_serviceresolveer().DeleteOperationAsync(id, a));

await Task.WhenAll(tasks);
0 голосов
/ 06 мая 2020

Вы можете использовать PLINQ (чтобы задействовать все процессоры вашей машины) и метод Task.WhenAll (чтобы не замораживать вызывающий поток). В коде получается что-то вроде этого:

class Program {
    static async Task Main(string[] args) {
        var list = new List<long> {
            4, 3, 2
        };

        var service = new Service();
        var response = 
            from item in list.AsParallel()
            select service.DeleteOperationAsync(item);
        await Task.WhenAll(response);

    }
}

public class Service {
    public async Task DeleteOperationAsync(long value) {
        await Task.Delay(2000);
        Console.WriteLine($"Finished... {value}");
    }
}
0 голосов
/ 06 мая 2020

Я не знаю, какой код стоит за этим DeleteOperationAsyn c, но наверняка async / await не предназначен для ускорения работы. Он был предназначен для «запасных» потоков (в просторечии)

Лучше всего было бы изменить метод так, чтобы он принимал в качестве параметра весь список идентификаторов, вместо того, чтобы принимать и отправлять только один идентификатор.

А затем выполнить эту тяжелую операцию async / await только один раз для всех идентификаторов.

Если это невозможно, вы можете просто запустить его параллельно, используя TPL (но он готов худший сценарий - реально :))

Parallel.ForEach(listOfIdsToDelete, 
async idToDelete => await _serviceresolver().DeleteOperationAsync(id,idToDelete)
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...