Task.Yield有点像携程中的yield return new WaitForEndOfFrame()
在unity中就是下一帧继续(首次await Task.Yield()后还是在当前帧的末尾,此后就是等下一帧)
当然继续还是在主线程中
async void RunTestTask()
{
    Debug.Log("ThreadId begin " + Thread.CurrentThread.ManagedThreadId.ToString());
    var testTask = TestTask();
    while (!testTask.IsCompleted) await Task.Yield();
    Debug.Log($"RunTestTask over rtn {testTask.Result} ManagedThreadId {Thread.CurrentThread.ManagedThreadId.ToString()}");
}
async Task<int> TestTask()
{
    Debug.Log("TestTask begin " + Thread.CurrentThread.ManagedThreadId.ToString());
    await Task.Delay(1000);
    Debug.Log("TestTask end " + Thread.CurrentThread.ManagedThreadId.ToString());
    return 998;
}
ThreadId begin 1
TestTask begin 1
TestTask end 1
RunTestTask over rtn 998 ManagedThreadId 1
 
 
Task.Run会启动一个新线程
async void RunTestTask2()
{
    Debug.Log("ThreadId begin " + Thread.CurrentThread.ManagedThreadId.ToString());
    var testTask = TaskYieldSimulation();
    while (!testTask.IsCompleted) await Task.Yield();
    Debug.Log($"RunTestTask over ");
}
Task TaskYieldSimulation()
{
    Debug.Log("TaskYieldSimulation before await, current thread id: {0}" + Thread.CurrentThread.ManagedThreadId.ToString());
    return Task.Run(() =>
    {
        Debug.Log("TaskYieldSimulation before ContinueWith, current thread id: {0}" + Thread.CurrentThread.ManagedThreadId.ToString());
        Thread.Sleep(3000);//阻塞线程3秒钟,模拟耗时的操作
        Debug.Log("TaskYieldSimulation ContinueWith!");
    }).ContinueWith(t =>
    {
        Debug.Log("TaskYieldSimulation after await, current thread id: {0}" + Thread.CurrentThread.ManagedThreadId.ToString());
        Thread.Sleep(3000);//阻塞线程3秒钟,模拟耗时的操作
        Debug.Log("TaskYieldSimulation finished!");
    });
}
ThreadId begin 1
TaskYieldSimulation before await, current thread id: 1
TaskYieldSimulation before ContinueWith, current thread id: 88
TaskYieldSimulation ContinueWith!
TaskYieldSimulation after await, current thread id: 88
TaskYieldSimulation finished!
RunTestTask over
 
以上两种方式均不会卡Unity主线程