C# wait语句后的代码不';跑不动

C# wait语句后的代码不';跑不动,c#,wpf,asynchronous,async-await,C#,Wpf,Asynchronous,Async Await,我知道论坛上有很多类似的问题,但我没有找到一个和我一样的问题。请看下面我的代码 public class MainViewModel { public MainViewModel() { Test(); } async Task<string> Test() { var v = await TaskCaller(); re

我知道论坛上有很多类似的问题,但我没有找到一个和我一样的问题。请看下面我的代码

public class MainViewModel
    {
        public MainViewModel()
        {
            Test();

        }

        async Task<string> Test()
        {
            var v = await TaskCaller();
            return v;
        }

        Task<string> TestTask()
        {
            new Task<string>(() =>
            {
                Thread.Sleep(2000);
                return "TestTask";
            });
            return null;
        }

        Task<string> TaskCaller()
        {
            var task = new Task<string>(() =>
            {
                return TestTask().Result;
            });

            return task;
        }
    }
public类主视图模型
{
公共主视图模型()
{
Test();
}
异步任务测试()
{
var v=等待TaskCaller();
返回v;
}
任务TestTask()
{
新任务(()=>
{
《睡眠》(2000年);
返回“TestTask”;
});
返回null;
}
任务TaskCaller()
{
变量任务=新任务(()=>
{
返回TestTask().Result;
});
返回任务;
}
}

永远不会到达return v语句。我需要TaskCaller的结果来执行更多流程。

您没有开始任何任务,因此它们可能无法完成(它们将永远停留在
状态=TaskStatus.Created
)。由于这些任务无法完成,您的
等待将无限期地等待。使用
Task.Run
,返回热(已启动)任务,以便安排线程池上的工作,即:

Task<string> TestTask()
{
    return Task.Run(() =>
    {
        Thread.Sleep(2000);
        return "TestTask";
    });
}
Task TestTask()
{
返回任务。运行(()=>
{
《睡眠》(2000年);
返回“TestTask”;
});
}
或者更好的选择:

async Task<string> TestTask()
{
    await Task.Delay(2000).ConfigureAwait(false);

    return "TestTask";
}
async Task TestTask()
{
等待任务。延迟(2000)。配置等待(false);
返回“TestTask”;
}
请注意,
TaskCaller
实际上返回一个空的
Task
。这显然是一个错误


另外:不要通过
Task.Wait()
Task.Result
阻止任务,因为您没有开始任何任务,因此它们可能无法完成(它们将永远停留在
Status=TaskStatus.Created
)。由于这些任务无法完成,您的
等待将无限期地等待。使用
Task.Run
,返回热(已启动)任务,以便安排线程池上的工作,即:

Task<string> TestTask()
{
    return Task.Run(() =>
    {
        Thread.Sleep(2000);
        return "TestTask";
    });
}
Task TestTask()
{
返回任务。运行(()=>
{
《睡眠》(2000年);
返回“TestTask”;
});
}
或者更好的选择:

async Task<string> TestTask()
{
    await Task.Delay(2000).ConfigureAwait(false);

    return "TestTask";
}
async Task TestTask()
{
等待任务。延迟(2000)。配置等待(false);
返回“TestTask”;
}
请注意,
TaskCaller
实际上返回一个空的
Task
。这显然是一个错误


另外:不要通过
Task.Wait()
Task.Result

阻塞任务。我在您的代码中做了一些更改

 async Task<string> Test()
        {
            try
            {
                var v = await TaskCaller();
                return v;
            }
            catch (Exception ee)
            {
                throw ee;
            }
        }

        async Task<string> TestTask()
        {
            string ty = string.Empty;
            Task<Task> task = new Task<Task>(async () =>
            {
                Thread.Sleep(2000);
                ty = "TestTask";
            });

            task.Start();
            task.Result.Wait();
            return ty;
        }

        async Task<string> TaskCaller()
        {
            string ty = string.Empty;
            Task<Task> task = new Task<Task>(async () =>
            {
                ty = await TestTask();
            });
            task.Start();
            task.Result.Wait();
            return ty;
        }
异步任务测试()
{
尝试
{
var v=等待TaskCaller();
返回v;
}
捕获(异常ee)
{
投掷物;
}
}
异步任务TestTask()
{
string ty=string.Empty;
任务=新任务(异步()=>
{
《睡眠》(2000年);
ty=“TestTask”;
});
task.Start();
task.Result.Wait();
返回y;
}
异步任务TaskCaller()
{
string ty=string.Empty;
任务=新任务(异步()=>
{
ty=等待TestTask();
});
task.Start();
task.Result.Wait();
返回y;
}

我对您的代码做了一些更改

 async Task<string> Test()
        {
            try
            {
                var v = await TaskCaller();
                return v;
            }
            catch (Exception ee)
            {
                throw ee;
            }
        }

        async Task<string> TestTask()
        {
            string ty = string.Empty;
            Task<Task> task = new Task<Task>(async () =>
            {
                Thread.Sleep(2000);
                ty = "TestTask";
            });

            task.Start();
            task.Result.Wait();
            return ty;
        }

        async Task<string> TaskCaller()
        {
            string ty = string.Empty;
            Task<Task> task = new Task<Task>(async () =>
            {
                ty = await TestTask();
            });
            task.Start();
            task.Result.Wait();
            return ty;
        }
异步任务测试()
{
尝试
{
var v=等待TaskCaller();
返回v;
}
捕获(异常ee)
{
投掷物;
}
}
异步任务TestTask()
{
string ty=string.Empty;
任务=新任务(异步()=>
{
《睡眠》(2000年);
ty=“TestTask”;
});
task.Start();
task.Result.Wait();
返回y;
}
异步任务TaskCaller()
{
string ty=string.Empty;
任务=新任务(异步()=>
{
ty=等待TestTask();
});
task.Start();
task.Result.Wait();
返回y;
}

Shlenskly将
ConfigureAwait(false)
do做什么?@Eldho,它使
await
后面的代码部分在线程池线程上执行。如果没有它,您的继续(在
等待
之后的所有内容)可能会在启动
任务
的同一线程上执行-对于UI应用程序来说是好的,对于非UI绑定的代码来说是坏的。一般规则是:如果您在第一次
等待
之后需要触摸UI,请不要使用
配置等待(false)
-只需等待您的
任务
。如果您不需要触摸UI,请使用它。Shlenskly如何
ConfigureAwait(false)
do?@Eldho,它会使
await
后面的代码部分在线程池线程上执行。如果没有它,您的继续(在
等待
之后的所有内容)可能会在启动
任务
的同一线程上执行-对于UI应用程序来说是好的,对于非UI绑定的代码来说是坏的。一般规则是:如果您在第一次
等待
之后需要触摸UI,请不要使用
配置等待(false)
-只需等待您的
任务
。如果您不需要触摸UI,请使用它。