Передача экземпляра задачи делегату задачи - PullRequest
4 голосов
/ 20 декабря 2011

У меня есть длительная задача, которая использует обратные вызовы для постепенной подачи данных (а не один обратный вызов ContinueWith () в конце).

Я хочу иметь возможность передать объект Task обратно в этом обратном вызове для целей идентификации задачи (используя Task.CurrentId)

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

например.

public Task StartDoingSomeStuff(CallbackDelegate callback)
{
    Task task = Task.Factory.StartNew(() =>
    {
         while(whatever)
         {
             var results = DoSomeStuff();
             callback(results, task); //CS0165. How do I get hold of the task?
         }
    });

    return task;
}

дает:

ошибка CS0165: использование неназначенной локальной переменной 'task'

Ответы [ 3 ]

5 голосов
/ 20 декабря 2011

Разделить объявление переменной и присвоение ей задачи на два оператора.Убедитесь, что вы не используете переменную до назначения задачи:

public Task StartDoingSomeStuff(CallbackDelegate callback)
{
    var gate = new object();
    lock (gate)
    {
        Task task = null;
        task = Task.Factory.StartNew(() =>
        {
            lock (gate)
            {
                while (whatever)
                {
                    var results = DoSomeStuff();
                    callback(results, task);
                }
            }
        });
        return task;
    }
}
1 голос
/ 20 декабря 2011

Другое решение состоит в том, чтобы создать ключ задачи и словарь, сопоставляющий ключи задачам, а затем передать ключ как состояние для действия задачи:

var taskMap = new Dictionary<object, Task>();
var taskKey = new object();
taskMap.Add(taskKey, Task.Factory.StartNew(key => { callback(results, key); }, taskKey));

Конечно, вам придется искать задачу по ключу, который может подходить или не соответствовать вашему сценарию.

0 голосов
/ 20 декабря 2011

Это должно работать, хотя это плохая практика:

public Task StartDoingSomeStuff(CallbackDelegate callback)
{
    Task task = null;

    task = Task.Factory.StartNew(() =>
    {
         while(whatever)
         {
             var results = DoSomeStuff();
             callback(results, task); //CS0165. How do I get hold of the task?
         }
    });

    return task;
}
...