首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >没有TaskCompletionSource的任务链?

没有TaskCompletionSource的任务链?
EN

Stack Overflow用户
提问于 2011-07-31 00:29:19
回答 3查看 2.5K关注 0票数 6

我正在将一些异步/等待代码转换为链式任务,这样我就可以在发布的框架中使用它。await代码如下所示

代码语言:javascript
复制
public async Task<TraumMessage> Get() {
  var message = await Invoke("GET");
  var memorized = await message.Memorize();
  return memorized;
}

哪里

代码语言:javascript
复制
Task<TraumMessage> Invoke(string verb) {}
Task<TraumMessage> Memorize() {}

我希望将InvokeMemorize链接起来,以返回Memorize生成的任务,但结果是生成了一个Task<Task<TraumMessage>。我最终得到的解决方案是一个TaskCompletionSource<TraumMessage>作为我的信号:

代码语言:javascript
复制
public Task<TraumMessage> Get() {
  var completion = new TaskCompletionSource<TraumMessage>();
  Invoke("GET").ContinueWith( t1 => {
     if(t1.IsFaulted) {
       completion.SetException(t1.Exception);
       return;
     }
     t1.Result.Memorize().ContinueWith( t2 => {
       if(t2.IsFaulted) {
         completion.SetException(t2.Exception);
         return;
       }
       completion.SetResult(t2.Result);
     });
  });
  return completion.Task;
}

有没有一种方法可以在没有TaskCompletionSource的情况下实现这一点

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-07-31 01:10:46

我认为这几乎是实现你想要的东西的唯一方法。延续API不支持将不同的任务链接在一起,因此您必须使用TaskCompletionSource,就像您必须协调工作一样。

我没有在这台机器上安装Async CTP,但是你为什么不用一个反编译器(或者ILDASM,如果你知道怎么读IL的话)来看看它在做什么。我敢打赌,它在幕后做的事情和你的TCS代码非常相似。

票数 1
EN

Stack Overflow用户

发布于 2012-04-25 21:20:05

是的,这个框架提供了一个方便的Unwrap()扩展方法来满足您的需求。

代码语言:javascript
复制
Invoke("GET").ContinueWith( t => t.Result.Memorize() ).Unwrap();

如果你正在进行取消操作,那么显然你需要将取消令牌传递到适当的位置。

票数 4
EN

Stack Overflow用户

发布于 2011-09-04 12:09:25

您可以使用附加的子任务。只有在所有子任务都完成时,父任务才会转换为已完成状态。异常将传播到父任务。您将需要一个结果容器,因为结果将在父任务的委托完成后分配,但将在父任务继续运行时设置。

如下所示:

代码语言:javascript
复制
public class Holder<T> where T: class
{
   public T Value { get; set; }
}

public Task<Holder<TraumMessage>> Get() {
  var invokeTask = Invoke("GET");
  var result = invokeTask.ContinueWith<Holder<TraumMessage>>(t1 => {
    var holder = new Holder<TraumMessage>();
    var memorizeTask = t1.Result.Memorize();
    memorizeTask.ContinueWith(t2 => {
      holder.Value = t2.Result;
    }, TaskContinuationOptions.AttachedToParent);
    return holder;
  });
  return result;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6884470

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档