C# 为什么这个异步单元测试会永远阻止线程?

C# 为什么这个异步单元测试会永远阻止线程?,c#,testing,asynchronous,async-await,nunit,C#,Testing,Asynchronous,Async Await,Nunit,目标 我想在C#中使用带有自定义扩展方法的Task组合异步工作流。我想对我将使用的每个基本扩展方法进行单元测试,以确保它们正常工作,这样当我开始将它们组合在一起时,行为上就不会有任何意外。此测试最重要的一个方面是确保这些方法在应该的时候运行任务,而不是在合成工作流时立即运行,而是在等待合成工作流时运行 实际上,我的扩展方法似乎工作得很好。但是,我无法创建一个单元测试,在不阻塞测试线程的情况下测试这些方法的等待方面 我使用的是Visual Studio 2015、C#5、.NET 4.5.1和NU

目标

我想在C#中使用带有自定义扩展方法的
Task
组合异步工作流。我想对我将使用的每个基本扩展方法进行单元测试,以确保它们正常工作,这样当我开始将它们组合在一起时,行为上就不会有任何意外。此测试最重要的一个方面是确保这些方法在应该的时候运行任务,而不是在合成工作流时立即运行,而是在等待合成工作流时运行

实际上,我的扩展方法似乎工作得很好。但是,我无法创建一个单元测试,在不阻塞测试线程的情况下测试这些方法的等待方面

我使用的是Visual Studio 2015、C#5、.NET 4.5.1和NUnit 3

代码

下面是我想测试的一种扩展方法:

public static async Task<T> Let<T>(this Task<T> source, Action<T> action)
{
    var result = await source;
    action(result);
    return result;
}
第一个测试按预期工作,但第二个测试在第一个
上阻塞,永远等待

研究

有趣的是,如果我删除被测试方法中的
wait
,测试将不会阻塞

public static async Task<T> Let<T>(this Task<T> source, Action<T> action)
{
    T result = default(T);
    action(result);
    return result;
}

Task.Run
将立即启动任务,这将允许我的第二次测试通过<代码>线程。需要睡眠
,以便第一次测试仍能通过。

如果您从未开始该任务,您将面临所谓的“冷任务”。等待不会启动任务,它只会等待任务完成


您永远不需要调用
新任务(
),除非您正在编写任务计划程序,否则请使用
Task.Run(
)创建一个热任务,该任务在函数返回后已处于运行状态。

如果您从未启动该任务,则您将拥有所谓的“冷任务”.Await不会启动任务,它只会等待任务完成

除非您正在编写任务计划程序,否则永远不需要调用
newtask(
),而是使用
Task.Run(
)创建一个热任务,该任务在函数返回后已处于运行状态

public static async Task<T> Let<T>(this Task<T> source, Action<T> action)
{
    T result = default(T);
    action(result);
    return result;
}
private static Task<int> Source =>
    Task.Run<int>(() => {
        Thread.Sleep(1000);
        sourceExecuted = true;
        return 1;
    });