Как получить доступ к аргументу задачи? - PullRequest
0 голосов
/ 06 ноября 2018

Предположим, у меня есть List<Task>:

private readonly List<Task> _tasks = new List<Task>(new Task[9]);

Я хочу создать Task для запуска метод DoWorkAsync, доступный внутри класса Foo, поэтому я сделал следующее:

_tasks[0] = new Task<Foo>(() => new Foo().DoWorkAsync());

поэтому класс Foo содержит метод DoWorkAsync, дизайн которого похож на этот:

public async Task HeavyAsync()
{
    while (true)
    {
        string newData = DateTime.Now.ToLongTimeString();
        Console.WriteLine(newData);
        await Task.Delay(200);
    }
}

На самом деле я могу запустить Task, используя _tasks[0].Start();.

Это работает, но главная проблема в том, что я хочу получить доступ к общедоступному свойству класса Foo и не могу этого сделать, потому что когда я набираю это: _tasks[0].

Я получу следующий метод:

enter image description here

Я также пытался использовать GetAwaiter() и await:

var foo = await _tasks[0];

но я получу следующую ошибку:

Невозможно назначить void локальной переменной с неявным типом

Как я могу получить доступ к Foo свойствам

1 Ответ

0 голосов
/ 06 ноября 2018

Вы должны изменить интерфейс вашего метода. Задача - это просто «указатель на функцию», который выполняется, а затем завершается. Если вам нужен объект, который содержит выполненную функцию, то вам нужно сохранить или вернуть его куда-нибудь.

Я бы сделал следующее: измените асинхронный метод, чтобы он возвращал объект вроде:

public async Task<Foo> HeavyAsync()
{
  while (true)
  {
    string newData = DateTime.Now.ToLongTimeString();
    Console.WriteLine(newData);
    await Task.Delay(200);
  }
  return this;
}

тогда это утверждение

var foo = await _tasks[0];

должен дать вам foo ссылку на ваш Foo-объект.

ОБНОВЛЕНИЕ:

Или вы предоставляете своему классу Foo следующее свойство и методы:

class Foo
{
    private Task runningTask {get;set;}

    public void StartTask()
    {
       runningTask = Task.Start( () => ....);
    }

    public async Task WaitTask()
    {
       await runningTask;
    }

    public bool IsRunning => runningTask != null && runningTask.Status......

И вместо того, чтобы держать список Task в вызывающем методе, вы можете хранить список экземпляров Foo.

...