如何获取当前任务参考?

Reu*_*ass 14 c# task-parallel-library

如何引用我的代码在其中执行的任务?

ISomeInterface impl = new SomeImplementation();
Task.Factory.StartNew(() => impl.MethodFromSomeInterface(), new MyState());

...

void MethodFromSomeInterface()
{
    Task currentTask = Task.GetCurrentTask();    // No such method?
    MyState state = (MyState) currentTask.AsyncState();
}
Run Code Online (Sandbox Code Playgroud)

因为我正在调用一些接口方法,所以我不能只将新创建的任务作为附加参数传递.

Ste*_*ary 7

由于您无法更改界面或实现,因此您必须自己完成,例如,使用ThreadStaticAttribute:

static class SomeInterfaceTask
{
  [ThreadStatic]
  static Task Current { get; set; }
}

...

ISomeInterface impl = new SomeImplementation();
Task task = null;
task = Task.Factory.StartNew(() =>
{
  SomeInterfaceTask.Current = task;
  impl.MethodFromSomeInterface();
}, new MyState());

...

void MethodFromSomeInterface()
{
  Task currentTask = SomeInterfaceTask.Current;
  MyState state = (MyState) currentTask.AsyncState();
}
Run Code Online (Sandbox Code Playgroud)

  • 在`task = Task.Factory.StartNew ...`和`SomeInterfaceTask.Current = task;`中设置任务对象之间存在竞争条件. (3认同)
  • 这真的是线程安全吗?事实上,除了在`StartNew`线程安全中使用lambda参数之外还有什么吗?在我看来,在lambda运行之前,`task`变量可能超出范围. (2认同)
  • 我明白你现在在说什么。但是线程池永远不会这样做;任何(完全同步)排队到线程池的工作,一旦开始,将始终运行到完成。实现“挂起当前正在运行的任务并在同一线程上运行另一个任务”将非常复杂,并导致*更糟*的性能*和*吞吐量,因此没有理由相信线程池会这样做. (2认同)