如何在BackgroundWorker类之外访问此线程的CancellationPending?

时间:2016-03-16 22:38:02

标签: c# .net multithreading

我有一个Windows服务,可以创建许多BackgroundWorkers。这些BackgroundWorkers的DoWork处理程序只包含SomeObject.DoSomeWork(),并且该方法(即DoSomeWork)不会引用BackgroundWorker。阻塞工作更深层次地发生。在具有阻塞工作的方法中,我想添加逻辑来测试拥有的BackgroundWorker的CancellationPending。如何???

我不想重构所有类来传递对BackgroundWorker的引用,我希望能够写出这样的东西;

(BackgroundWorker(Thread.CurrentThread)).CancellationPending

但这显然不起作用,因为BackgroundWorker本身不是一个线程。

我没有尝试任何事情,因为我没有想过要尝试的任何事情。我已经Google搜索了很多并且阅读了很多但没有找到任何指向正确方向的东西。可能是这样的情况,这是不可能的(至少不可能没有得到太多hacky)在​​这种情况下,我将不得不考虑一个不同的方法来解决问题,但我需要一个比我更聪明的人来告诉我这是不可能的: )

3 个答案:

答案 0 :(得分:2)

有一个黑客可以做到这一点。如果没有其他选择,请仅使用此选项。您可以使用线程局部变量使BackgroundWorker在当前线程的任何位置都可用。

[ThreadStatic]
static BackgroundWorker bw;

然后,您需要维护此变量:

try {
 bw = ...;
 DoSomeWork();
}
finally { bw = null; }

答案 1 :(得分:0)

您可以拥有一个集合ember serve,用于存储对象和后台工作者引用,然后是扩展方法:

Dictionary<MyObject, BackgroundWorker>

可以从您的对象调用此扩展方法:

public static void CancelWork(this MyObjectObject myObj)
{
  var kvp = dictionary.FirstOrDefault(o => o.Key.equals(myObj));

  if(kvp.Key == null) return;

  // TODO
  // Call the background worker cancellation from the kvp.Value
}

答案 2 :(得分:0)

与@ Panda的回答类似,您可以拥有一个静态Dictionary<int, BackgroundWorker> workers;集合,并将其填入DoWork处理程序的开头:

workers[Thread.CurrentThread.ManagedThreadId] = sender as BackgroundWorker;

然后在你的DoSomeWork中使用它:

bw = workers[Thread.CurrentThread.ManagedThreadId];
// use bw.CancellationPending

但请注意同步此集合,最好使用ConcurrentDictionary。还有一件事,你应该确保你的DoWork处理程序只在一个线程中运行才能实现。