子线程如何等待主线程中的某事完成?

How can a child thread wait for something in the main thread to complete?

通常问题是主线程等待子线程,我可以在 Task 上使用 await

但我有一种情况,子线程必须等待主线程中的某些方法完成才能继续。如何让这种沟通成为可能?

public void MainThread()
{
    Task t = Task.Run(ChildThread); //not using await because we want to continue doing work that must be only on the main thread
    WorkA();
    WorkB();
    ???
    WorkC();
}

public async Task ChildThread()
{
    WorkD();
    ???
    Need_WorkB_ToBeCompletedBeforeThisOne();
}

WorkA WorkB WorkC 都是主线程所必需的。在我的真实代码中,所有这些都是从子线程间接发出的,因为子线程需要完成它们但由于线程限制而无法完成。

我有办法让我的子线程告诉主线程已经开始工作(所以我将代码简化为您在此处看到的内容,任务一开始工作就会立即跟进)但我需要一些方法让发行者(子线程)了解这些命令的进度。

PS。感谢这个线程的回答,我为 Unity 创建了 CoroutineHost,你可以 await yield IEnumerator 方法,你可以从你的任何子线程发出到你的主线程来完成: https://github.com/5argon/E7Unity/tree/master/CoroutineHost

如果 WorkB 是一个任务,我会想象这样的事情:

public void MainThread()
{
    Task workB = WorkB();
    ChildThread(workB); // you don't need to use Task.Run here, the task is ran automatically
    WorkA();
    WorkC();
}

public async Task ChildThread(Task otherTaskToWait)
{
    WorkD();
    await otherTaskToWait;
    Need_WorkB_ToBeCompletedBeforeThisOne();
}

您正在寻找 "signal"。由于 child 是异步的并且信号仅使用一次,因此 TaskCompletionSource<T> 可以很好地工作:

public void MainThread()
{
  var tcs = new TaskCompletionSource<object>(); // Create the signal
  Task t = Task.Run(() => ChildThread(tcs.Task)); // Pass the "receiver" end to ChildThread
  WorkA();
  WorkB();
  tcs.SetResult(null); // Send the signal
  WorkC();
}

public async Task ChildThread(Task workBCompleted)
{
  WorkD();
  await workBCompleted; // (asynchronously) wait for the signal to be sent
  Need_WorkB_ToBeCompletedBeforeThisOne();
}

参见 my book for more information. If you need a "signal" that can become set and unset multiple times, then you should use AsyncManualResetEvent 中的技巧 11.4 "Async Signals"。