Question about UniTask.WhenAll
Closed this issue · 4 comments
After using UniTask.WhenAll it switches to main thread. Has any proper way to not switch to leave after UniTask.WhenAll on thread pool? Sorry if it's dumb question ;)
var task1 = GetTextAsync(UnityWebRequest.Get("http://google.com"));
var task2 = GetTextAsync(UnityWebRequest.Get("http://bing.com"));
var task3 = GetTextAsync(UnityWebRequest.Get("http://yahoo.com"));
// concurrent async-wait and get results easily by tuple syntax
var (google, bing, yahoo) = await UniTask.WhenAll(task1, task2, task3);
It will be executed on the thread that was last awaited in the parallel state.
UnityWebRequest appears to run on the main thread because it is called back on Unity's main thread itself.
It is not possible to return to the original thread.
If you want to return to the thread pool, you need to take measures such as switching back to the thread pool (SwitchToThreadPool).
@neuecc , Please explain this test. I don't understand why after WhenAll Here I ended up on the main thread.
public class UniTaskTests
{
[Test]
public async Task Test()
{
Debug.LogFormat(
"I'm starting on {0} ({1})",
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread
);
await UniTask.RunOnThreadPool(() => GlobalTask());
Debug.LogFormat(
"I'm finished on {0} ({1})",
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread
);
}
private async UniTask<bool> GlobalTask()
{
Debug.LogFormat(
"Global task starting on {0} ({1})",
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread
);
var (r1, r2, r3) = await UniTask.WhenAll(
UniTask.RunOnThreadPool(() => SubTask(1)),
UniTask.RunOnThreadPool(() => SubTask(2)),
UniTask.RunOnThreadPool(() => SubTask(3))
);
Debug.LogFormat(
"Global task after WhenAll on {0} ({1})",
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread
);
return true;
}
private async UniTask<bool> SubTask(int n)
{
Debug.LogFormat(
"Subtask {0} on {1} ({2})",
n,
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread
);
for (int i = 0; i < 100000000; i++)
{
var example = Mathf.Pow(2, 10);
}
Debug.LogFormat(
"Subtask {0} finished on {1} ({2})",
n,
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread
);
return true;
}
}
Test Output:
I'm starting on 1 (False)
Global task starting on 13013 (True)
Subtask 1 on 13013 (True)
Subtask 2 on 13011 (True)
Subtask 3 on 13009 (True)
Subtask 1 finished on 13013 (True)
Subtask 2 finished on 13011 (True)
Subtask 3 finished on 13009 (True)
Global task after WhenAll on 1 (False)
I'm finished on 1 (False)
RunOnThreadPool
has (bool configureAwait = true)
argument.
If true(default) returns main thread automatically.
Thanks i've got it!