Следуя этому вопросу, я пытаюсь реализовать метод async с использованием TPL и пытаюсь следовать рекомендациям TAP.
Я хочу, чтобы мой метод async выполнял обратный вызов, когда он закончил. Насколько я вижу, есть три способа, которыми я могу это сделать.
1) Обратный вызов вручную в моей делегате задач
public Task DoWorkAsync(DoWorkCompletedCallback completedCallback)
{
return Task.Factory.StartNew(
{
//do work
//call callback manually
completedCallback();
});
}
2) Назначить обратный вызов для задачи в делегате задачи
public Task DoWorkAsync(DoWorkCompletedCallback completedCallback)
{
return Task.Factory.StartNew(
{
//do work
}
).ContinueWith(completedCallback); //assign callback to Task
}
3) Назначить обратный вызов для задачи в вызывающем абоненте
public Task DoWorkAsync()
{
return Task.Factory.StartNew(
{
//do work
});
}
public void SomeClientCode()
{
Task doingWork = DoWorkAsync();
doingWork.ContinueWith(OnWorkCompleted);
}
У меня возникает ощущение, что 3 правильнее, потому что он отделяет обратный вызов от метода и означает, что клиентский код может управлять задачей любым способом, который он считает нужным (используя обратные вызовы, опрос и т.д.), что, кажется, является тем, что задает все о. Однако, что произойдет, если DoWorkAsync() завершит свою работу до того, как клиентский код подключит свой обратный вызов?
Есть ли общепринятый способ сделать это или он слишком новый?
Есть ли преимущество в выполнении 2) над 1)?