【发布时间】:2019-10-16 18:38:12
【问题描述】:
我有一些使用 xUnit 的集成测试需要拆除在测试期间创建的一些资源。为此,我在包含测试的类中实现了IDisposable。
问题是我需要使用只有异步接口的客户端删除测试期间创建的资源。但是,Dispose 方法是同步的。
我可以使用.Result 或.Wait() 来等待异步调用的完成,但这可能会造成死锁(这个问题有据可查的here)。
鉴于我不能使用.Result 或.Wait(),在Dispose 方法中调用异步方法的正确(和安全)方法是什么?
更新:添加一个(简化的)示例来说明问题。
[Collection("IntegrationTests")]
public class SomeIntegrationTests : IDisposable {
private readonly IClient _client; // SDK client for external API
public SomeIntegrationTests() {
// initialize client
}
[Fact]
public async Task Test1() {
await _client
.ExecuteAsync(/* a request that creates resources */);
// some assertions
}
public void Dispose() {
_client
.ExecuteAsync(/* a request to delete previously created resources */)
.Wait(); // this may create a deadlock
}
}
【问题讨论】:
-
你能告诉我你的异步处理方法吗?还没有真正听说过异步处理自己的接口。在处理类之前,您绝对需要等待异步处理完成吗?异步对象终结器尚未实现。 github.com/dotnet/coreclr/issues/22598
-
@AvinKavish 刚刚添加了一个示例
-
我猜删除逻辑是测试方法独有的?将
teardown逻辑移动到测试本身应该没问题。 xUnit 的作者告诉你原因。 jamesnewkirk.typepad.com/posts/2007/09/why-you-should-.html -
您在使用
.GetAwaiter().GetResult()之类的东西时是否真的遇到了问题,或者您是否试图避免出现问题?如果您不在同步上下文(UI 应用程序..)中运行,那还不错。如果您不需要“等待”处置,您也可以触发异步执行而不等待它完成 - 例如async void- 只需通过添加 try/catch 来确保不会导致未处理的异常 -
如果您绝对需要,请在 xunit 上提交问题以支持即将在 .net core 3.0 中推出的
IAsyncDisposable。
标签: c# asp.net-core .net-core async-await xunit