gpt4 book ai didi

c# - 嵌套的 BackgroundWorkers : RunWorkerCompleted calls on wrong thread?

转载 作者:太空狗 更新时间:2023-10-30 01:10:37 26 4
gpt4 key购买 nike

我正在处理需要调用更多异步任务的异步操作。我试图通过使用 BackgroundWorkers 来保持简单,结果是一个 BackgroundWorker 的 DoWork() 回调调用一个创建第二个 BackgroundWorker 的方法,就像这样(为了简洁起见减去错误检查和所有爵士乐):

class Class1
{
private BackgroundWorker _worker = null;

public void DoSomethingAsync()
{
_worker = new BackgroundWorker();
_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker_RunWorkerCompleted);
_worker.DoWork += new DoWorkEventHandler(_worker_DoWork);
_worker.RunWorkerAsync();
}

void _worker_DoWork(object sender, DoWorkEventArgs e)
{
Class2 foo = new Class2();
foo.DoSomethingElseAsync();
while(foo.IsBusy) Thread.Sleep(0); // try to wait for foo to finish.
}

void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// do stuff
}
}

class Class2
{
private BackgroundWorker _worker = null;
Thread _originalThread = null;

public AsyncCompletedEventHandler DoSomethingCompleted;

public bool IsBusy { get { return _worker != null && _worker.IsBusy; } }

public void DoSomethingElseAsync()
{
_originalThread = Thread.CurrentThread;

_worker = new BackgroundWorker();
_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker_RunWorkerCompleted);
_worker.DoWork += new DoWorkEventHandler(_worker_DoWork);
_worker.RunWorkerAsync();
}

void _worker_DoWork(object sender, DoWorkEventArgs e)
{
// do stuff
}

void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Debug.Assert(Thread.CurrentThread == _originalThread); // fails

// Assuming the above Assert() were excluded, the following event would be raised on the wrong thread.
if (DoSomethingCompleted != null) DoSomethingCompleted(this, new AsyncCompletedEventArgs(e.Error, e.Cancelled, null));
}
}

所以问题是,我希望 Class2._Worker_RunWorkerCompleted() 在调用 Class2.DoSomethingElseAsync() 的同一线程上执行。这永远不会发生 - 相反,回调在一个全新的线程上运行。

这是我的怀疑:Class1 的 _worker_DoWork() 永远不会返回,这意味着该线程永远不会返回到事件监听器,即使存在(我怀疑一个不存在)。另一方面,如果 _worker_DoWork() 确实返回,Class1 的 BackgroundWorker 将自动提前完成 - 它需要等待 Class2 完成工作才能完成其工作。

这引出了两个问题:

  1. 我的怀疑是否正确?
  2. 像这样嵌套异步操作的最佳方式是什么?我可以挽救 BackgroundWorker 方法,还是有其他更合适的技术?

最佳答案

如果 BackgroundWorker 在 UI 线程上创建,DoWork 将在线程池线程上运行,而 RunWorkerCompleted 将在 UI 线程上运行.

如果 BackgroundWorker 是在后台线程(即不是 UI 线程)上创建的,DoWork 仍将在线程池线程和 RunWorkerCompleted 还将在线程池线程上运行。

在你的情况下,由于你不能编码对任意(线程池)线程的调用,你将无法保证你想要的行为,尽管你可能想看看 System .Threading.SynchronizationContext.

关于c# - 嵌套的 BackgroundWorkers : RunWorkerCompleted calls on wrong thread?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4262441/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com