2012-07-16 34 views
3

我们在深度抽象程序集中的某个地方存在从OperationContext.Current中读取数据的WCF行为,当此代码从Task中执行时,OperationContext.Current为空,是否可以在抽象程序集内部解决这个问题,还是需要向这个程序集的所有消费者添加一些代码?在任务并行库中保留OperationContext

+0

谁开始“任务”?消费者?在启动“Task”之前是否执行了抽象程序集的任何代码? – svick 2012-07-16 08:46:40

+0

不,这是问题,消费者开始的任务:( – 2012-07-16 09:07:08

回答

0

似乎是唯一的办法就是添加一些的CallContext中,就像目前的主要存储...

1

点在哪里您创建Task instance,你应该使用一个封闭,像这样:

// The operation context. 
OperationContext oc = OperationContext.Current; 

Task t = Task.Factory.StartNew(() => { 
    // Do something with context here, it will be valid for 
    // the life of the operation. 
}; 

您也可以拨打overload of StartNew这需要一个state参数并通过OperationContext instance中,铸造和使用它需要在Task的时候,像这样:

Task t = Task.Factory.StartNew(s => { 
    // s is an object, so need to cast here. 
    var oc = (OperationContext) c; 

    // Work with the OperationContext. 
}, 
// Note, this is passed to the delegate through the 's' parameter. 
OperationContext.Current); 

注意,在这两种情况下,OperationContext只会有利于操作的使用寿命。该操作的完成应取决于Task的完成情况。

如果你推出一个Task将运行在操作完成后,那么你应该从你的OperationContext需要的值那些复制到另一个结构的方式传递到Task进行处理。

+0

是的,我知道,但问题是不能强制消费者代码不只是启动一个任务,并做的东西:) – 2012-07-17 07:14:21

+0

@TimMahy然后,你似乎必须在抽象中构建上下文,并将其传递到需要的地方。 – casperOne 2012-07-17 11:49:45

2

正面临着类似的问题。通过任务调用服务。 下面的代码片断解决了。 OperationContext.Current明确地通过在服务调用完成之前投射由Task提供的state变量来设置。

Task<int> taskContactsCount = Task.Factory.StartNew<int>((state) => 
     { 
      int count = 0; 
      try 
      { 
       OperationContext.Current = (OperationContext)state; 
       TestServiceClient testServiceProxy = new TestServiceClient(); 
       var count = testServiceProxy.GetCount(); 
      } 
      catch (Exception ex) 
      { 
      } 
      return contactsCount; 
     }, OperationContext.Current);