C# 用wait编写异步方法?
当将方法调用传递给另一个异步方法时,调用方方法是否也应该是异步的并使用wait,或者我应该简单地传递它从被调用方接收到的任务?如果调用方法执行更多的准备工作,该怎么办C# 用wait编写异步方法?,c#,.net,asynchronous,async-await,C#,.net,Asynchronous,Async Await,当将方法调用传递给另一个异步方法时,调用方方法是否也应该是异步的并使用wait,或者我应该简单地传递它从被调用方接收到的任务?如果调用方法执行更多的准备工作,该怎么办 public Task<Message> Unsubscribe(int subscriptionId, CancellationToken cancellationToken) { var data = new MessageData { ["subscriptionId"] = su
public Task<Message> Unsubscribe(int subscriptionId, CancellationToken cancellationToken)
{
var data = new MessageData
{
["subscriptionId"] = subscriptionId
};
return SendAsync(OpCode.Unsubscribe, data, cancellationToken);
}
public Task<Message> Unsubscribe(int subscriptionId) =>
Unsubscribe(subscriptionId, CancellationToken.None);
另一种选择是第二次重载取消订阅
。它可能像上面或那样:
public async Task<Message> Unsubscribe(int subscriptionId, CancellationToken cancellationToken)
{
var data = new MessageData
{
["subscriptionId"] = subscriptionId
};
return await SendAsync(OpCode.Unsubscribe, data, cancellationToken);
}
public async Task<Message> Unsubscribe(int subscriptionId) =>
await Unsubscribe(subscriptionId, CancellationToken.None);
公共异步任务取消订阅(int subscriptionId)=>
等待取消订阅(subscriptionId、CancellationToken.None);
我猜更多的异步和等待会增加编译器引入的复杂性(我在堆栈跟踪中看到了!),并可能降低性能和内存消耗。但至少它应该提供一致的异常传播。在您引用的示例中,只返回任务而不等待它是好的(可以说是更好的),但这确实需要一些注意 当您在
块中处理任务时,您可能会遇到麻烦。它们可能有截然不同的行为:
public async Task<Something> AwaitTheTask()
{
using (var someResource = GetAResource())
{
return await SomeAsyncThing(someResource);
}
}
public Task<Something> DontAwaitTheTask()
{
using (var someResource = GetAResource())
{
return SomeAsyncThing(someResource);
}
}
公共异步任务等待任务()
{
使用(var someResource=GetAResource())
{
返回等待某物(某物资源);
}
}
公共任务DontAwaitTheTask()
{
使用(var someResource=GetAResource())
{
返回某物(某物资源);
}
}
在第一个示例中,在等待的任务完成之前,using
块不会处理someResource
。在第二个示例中,someResource
将立即被处置,这很可能会给需要该资源的代码带来问题。在您引用的示例中,只返回任务而不等待它是好的(可以说是更好的),但这确实需要一些注意
当您在块中处理任务时,您可能会遇到麻烦。它们可能有截然不同的行为:
public async Task<Something> AwaitTheTask()
{
using (var someResource = GetAResource())
{
return await SomeAsyncThing(someResource);
}
}
public Task<Something> DontAwaitTheTask()
{
using (var someResource = GetAResource())
{
return SomeAsyncThing(someResource);
}
}
公共异步任务等待任务()
{
使用(var someResource=GetAResource())
{
返回等待某物(某物资源);
}
}
公共任务DontAwaitTheTask()
{
使用(var someResource=GetAResource())
{
返回某物(某物资源);
}
}
在第一个示例中,在等待的任务完成之前,using
块不会处理someResource
。在第二个示例中,someResource
将立即被释放,这很可能会导致需要该资源的代码出现问题。还有其他细微的区别。特别是,您应该使用ConfigureAwait(false)
;否则,您的第二个版本可能会出现死锁。“SendAsync是异步的”是SendAsync()的内部事务。对于来电者来说,这是一个值得期待的消息。Unsubscribe()的两个版本也是如此。有更多类似的问题,但我选择的dupe提供了更好的解释和链接。还有其他细微的区别。特别是,您应该使用ConfigureAwait(false)
;否则,您的第二个版本可能会出现死锁。“SendAsync是异步的”是SendAsync()的内部事务。对于来电者来说,这是一个值得期待的消息。Unsubscribe()的两个版本也是如此。有更多类似的问题,但我选择的dupe提供了更好的解释和链接。谢谢。对我来说,很明显,您的两个示例的行为不同,因为在等待
之后发生了一些事情,如果我不等待,这些事情会更早发生。@ygoe好吧,这对我来说不是很明显,我必须通过艰苦的学习(^^);如果一个人不知道如何去寻找,很容易忘记这样的事情。谢谢。对我来说,很明显,您的两个示例的行为不同,因为在等待
之后发生了一些事情,如果我不等待,这些事情会更早发生。@ygoe好吧,这对我来说不是很明显,我必须通过艰苦的学习(^^);如果一个人不知道如何寻找,那么很容易忘记这样的事情。