Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用wait编写异步方法?_C#_.net_Asynchronous_Async Await - Fatal编程技术网

C# 用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

当将方法调用传递给另一个异步方法时,调用方方法是否也应该是异步的并使用wait,或者我应该简单地传递它从被调用方接收到的任务?如果调用方法执行更多的准备工作,该怎么办

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好吧,这对我来说不是很明显,我必须通过艰苦的学习(^^);如果一个人不知道如何寻找,那么很容易忘记这样的事情。