как назначить возвращаемое значение задачи для некоторой переменной в TPL C # - PullRequest
0 голосов
/ 20 февраля 2019

Это моя C# функция

public async Task GetAttendance(IEnumerable<Zone> zones)
{
    try
    {
        foreach (var zone in zones)
        {
            var req = new AttendeeRequestTO(zone.StartTime, zone.EndTime, zone.ZoneId.ToString(), accessToken);

            //THROWING COMPILE TIME ERROR
            zone.AttendanceCount = Task.Factory.StartNew(() => _vClient.GetAttendeesCount(req));
        }
    }
    catch (Exception ex)
    {
    }
}

Ошибка

Ошибка CS0029 Не удается неявно преобразовать тип 'System.Threading.Tasks.Task>' в 'int?'

Я не хочу применять ожидание для каждой Задачи, поскольку каждая Задача является независимой, и я хочу, чтобы каждая Задача выполнялась в своем собственном контексте, не ожидая выполнения какой-либо другой Задачи.

Я имею в видуЗадача T1 - перейти к API, получить значение и установить количествоЗадача T2 - перейти к API, получить значение и установить количествоЗадача T3 - перейти к API, получить значение и установить счетчик

T2 не должен ждать завершения T1, T3 не должен ждать завершения T2 и т. Д.

Как мнеприсвойте значение выходных данных каждой задачи zone.AttendanceCount?

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Способ выполнения асинхронного параллелизма состоит в том, чтобы вызвать каждый асинхронный метод без , используя await, а затем использовать await Task.WhenAll.

Поскольку у вас есть коллекция, и вам нужна задача длякаждый из них, вы можете вызывать каждый асинхронный метод, используя LINQ:

var tasks = zones.Select(async zone =>
{
  var req = new AttendeeRequestTO(zone.StartTime, zone.EndTime, zone.ZoneId.ToString(), accessToken);
  zone.AttendanceCount = await Task.Run(() => _vClient.GetAttendeesCount(req));
}).ToList();
await Task.WhenAll(tasks);

Обратите внимание, что я также изменил StartNew на Run.

Было бы лучшеесли возможно, использовать метод GetAttendeesCountAsync на вашем клиенте (при условии, что он выполняет вызов ввода / вывода).Если этот метод доступен, вы можете избежать ненужного использования пула потоков:

var tasks = zones.Select(async zone =>
{
  var req = new AttendeeRequestTO(zone.StartTime, zone.EndTime, zone.ZoneId.ToString(), accessToken);
  zone.AttendanceCount = await _vClient.GetAttendeesCountAsync(req);
}).ToList();
await Task.WhenAll(tasks);
0 голосов
/ 20 февраля 2019

Task.Factory.StartNew возвращает задачу или задачу , поэтому, если вы хотите получить результат, возвращаемый асинхронной операцией, вы должны дождаться его.

Вам просто нужно добавить await:

zone.AttendanceCount = await Task.Factory.StartNew(() => _vClient.GetAttendeesCount(req));

Обратите внимание, что рекомендуется использовать Task.Run вместо Task.Factory.StartNew.

...