【问题标题】:How can I wrap a method with a callback parameter into a Task?如何将带有回调参数的方法包装到任务中?
【发布时间】:2012-01-31 19:24:47
【问题描述】:

我有一个 Silverlight 5 应用程序,其中包含一堆签名类似于此的方法:

public void AskConfirmation(Action<bool> callback);

通常,这些方法会引发一个 InteractionRequest 来与用户交互,等待输入。

我想利用任务并行库和 async/await 关键字,因此我想定义具有以下签名的第二种方法:

public Task<bool> AskConfirmation();

而第二种方法将依赖于第一种方法。不幸的是,我只是不知道如何实现它。

当异步操作遵循基于事件的异步模式或开始/结束模式时,将异步操作包装到任务中很容易,但在我的情况下,这些显然是矫枉过正,所以我不想实现它们。但现在我被困住了。有没有人遇到过同样的问题并找到了解决方案?

【问题讨论】:

标签: c# callback task-parallel-library silverlight-5.0


【解决方案1】:
public Task<bool> AskConfirmation()
{
    var tcs = new TaskCompletionSource<bool>();
    AskConfirmation(b => tcs.TrySetResult(b));
    return tcs.Task;
}

【讨论】:

  • 很好的答案!只是一件事,你应该用 try/catch 和 tcs.TrySetException 包装“AskConfirmation”
  • @Maxim 实际上这将违反 Task.FromAsync 的约定,它会抛出 BeginMethod 抛出的任何异常,而不是返回错误的任务:msdn.microsoft.com/en-us/library/dd321404.aspx
  • 感谢这个简单的回答!不过有一件事困扰着我:在调用它返回的 Task 的 Start() 方法之前,这个方法不应该没有副作用吗?调用此方法来接收 Task 对象实际上会立即“启动”它。我不应该以后再启动它(或根本不启动)吗?我当然可以忍受这个,但是...... :)
  • 你是对的。我错过了另一件事,当然这取决于需要,但我认为最好在新任务中启动 AskConfirmation,这样方法将在方法完成之前返回。然后如果它抛出一个异常你应该设置任务异常。
  • @jpatte, Maxim:我给出的方法遵循推荐的模式,参见blogs.msdn.com/b/pfxteam/archive/2010/06/13/10024153.aspx。这也是Task.FromAsync 所做的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-15
  • 2014-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多