C# 当async/await关键字为';你没用过吗?

C# 当async/await关键字为';你没用过吗?,c#,unit-testing,nunit,async-await,mstest,C#,Unit Testing,Nunit,Async Await,Mstest,根据,以下两种方法之间应该没有区别: public async Task Foo() { await DoSomethingAsync(); } public Task Foo() { return DoSomethingAsync(); } 实际上,对于非常简单的方法,不使用async/await关键字的调用似乎更可取,因为它们会减少一些开销 然而,这显然并不总是在单元测试中起作用 MSTest [TestClass] public class AsyncTest {

根据,以下两种方法之间应该没有区别:

public async Task Foo()
{
    await DoSomethingAsync();
}

public Task Foo()
{
    return DoSomethingAsync();
}
实际上,对于非常简单的方法,不使用async/await关键字的调用似乎更可取,因为它们会减少一些开销

然而,这显然并不总是在单元测试中起作用

MSTest

[TestClass]
public class AsyncTest
{
    [TestMethod]
    public async Task Test1()
    {
        await Task.Delay(0);
    }

    [TestMethod]
    public Task Test2()
    {
        return Task.Delay(0);
    }
}
[TestFixture]
public class AsyncTest
{
    [Test]
    public async Task Test1()
    {
        await Task.Delay(0);
    }

    [Test]
    public Task Test2()
    {
        return Task.Delay(0);
    }
}
public class AsyncTest
{
    [Fact]
    public async Task Test1()
    {
        await Task.Delay(0);
    }

    [Fact]
    public Task Test2()
    {
        return Task.Delay(0);
    }
}
NUnit

[TestClass]
public class AsyncTest
{
    [TestMethod]
    public async Task Test1()
    {
        await Task.Delay(0);
    }

    [TestMethod]
    public Task Test2()
    {
        return Task.Delay(0);
    }
}
[TestFixture]
public class AsyncTest
{
    [Test]
    public async Task Test1()
    {
        await Task.Delay(0);
    }

    [Test]
    public Task Test2()
    {
        return Task.Delay(0);
    }
}
public class AsyncTest
{
    [Fact]
    public async Task Test1()
    {
        await Task.Delay(0);
    }

    [Fact]
    public Task Test2()
    {
        return Task.Delay(0);
    }
}
XUnit

[TestClass]
public class AsyncTest
{
    [TestMethod]
    public async Task Test1()
    {
        await Task.Delay(0);
    }

    [TestMethod]
    public Task Test2()
    {
        return Task.Delay(0);
    }
}
[TestFixture]
public class AsyncTest
{
    [Test]
    public async Task Test1()
    {
        await Task.Delay(0);
    }

    [Test]
    public Task Test2()
    {
        return Task.Delay(0);
    }
}
public class AsyncTest
{
    [Fact]
    public async Task Test1()
    {
        await Task.Delay(0);
    }

    [Fact]
    public Task Test2()
    {
        return Task.Delay(0);
    }
}
  • 在所有情况下,
    Test1
    都通过
  • 在MSTest中,
    Test2
    显示在测试运行程序中,但它不运行
  • 在NUnit中,
    Test2
    被忽略,并显示以下消息:

    测试方法具有非无效返回类型,但预期不会有结果

  • 在XUnit中,
    Test2
    通过


由于任务在所有情况下都是可以等待的,那么影响NUnit和MSTest测试运行程序的
async
关键字是什么?可能是反射问题?

听起来这些测试运行人员可能在使用反射来检查返回
任务的方法是否真的是异步方法。这并不意味着如果方法运行,它们的行为会有所不同,但它们只是没有被运行

就像说:

public string Name { get; set; }
相当于:

private string name;
public Name { get { return name; } set { name = value; } }
从逻辑上讲,他们的行为是相同的,但如果你足够努力地思考,你就能分辨出其中的差异。在这种特殊情况下,还有其他更微妙的区别,但同样的一般原则适用

在当前NUnit代码中(在编写本文时),检测似乎处于激活状态


诚然,编写一个返回
任务但不使用异步方法的单元测试至少是不寻常的,但这绝非不可能。

我明白了。因此NUnit特别希望编译器用
AsyncStateMachineAttribute
修饰该方法。我想这就是原因。MSTest可能也在做类似的事情。@MattJohnson:我想你当然可以自己添加这个属性,只是为了愚弄它。也许值得一试,看看MSTest做了什么…是的。添加了
[AsyncStateMachine(typeof(Task))]
,现在通过了MSTest和NUnit。尽管我认为我会坚持使用async/await关键字。:)实际上,在
Test1
Test2
之间有:)@nosratio-谢谢!