任务的返回类型是否足以使方法异步运行?

问题描述 投票:-2回答:3

我有一个简单的方法,可以执行复杂的字符串操作并返回结果。如您所见,此方法的返回类型为Task<string>。因此,我可以使用Task.FromResult(result)返回我的字符串的值。

public Task<string> ComplexOperation()
{
    string result = // Do something complex
    return Task.FromResult(result);
}

然后,我可以使用await关键字来调用此方法。

public static async Task Main(string[] args)
{
    var myResult = await ComplexOperation();
}

由于我正在等待CompelxOperation(),(等待Task完成返回),此方法会异步运行吗?

c# asynchronous async-await task-parallel-library
3个回答
3
投票

根据您的评论,您需要执行以下操作:

public Task<string> ComplexOperation()
{
    return Task.Run(() =>  /* Do something complex */);
}

您可以像这样玩:

public static async Task Main()
{
    Console.WriteLine("Before" );
    var myResultTask = ComplexOperation();
    Console.WriteLine("After task creation");
    var result = await myResultTask;
    Console.WriteLine("After async await");
}

public Task<string> ComplexOperation()
{    
    Console.WriteLine("Creation");
    return Task.Run(() =>
    {
        Console.WriteLine("In before work");
        Thread.Sleep(500); //simulate work;
        Console.WriteLine("In after work");
        return "Done";
    });
}

并在刚返回Task.FromResult时将行为与切换到实现进行比较。同样在这样的测试示例TBH中也没有多大意义。


-2
投票

就像您将Main方法标记为异步以获取异步方法一样,您需要使用async关键字将该方法标记为异步,并将结果设为Task。

但是在框架中,任务用于2个相关但不同的概念,并行化和异步编程。

您正在做的是使用并行化。

所以您只是在其他线程上运行一些同步代码。

根据您的示例,我认为您需要使用并行化,这可以加快一些复杂的计算速度,或者通过使用多个线程来并行工作。

异步代码背后的概念是在等待外部资源(例如来自Web服务的某些数据)时释放线程,以允许同时进行其他工作。

因此,如果需要使用本地资源进行复杂的工作,最好使用没有异步逻辑的任务,而当使用远程资源时,可以进行异步操作。


-2
投票

语义上,方法ComplexOperation是异步的,因为它返回一个可等待的类型,并且为了跟随the guidelines,应将其命名为ComplexOperationAsync

在TAP中,异步方法在返回可等待类型(例如AsyncTaskTask<TResult>ValueTask等类型的方法的操作名称后包含ValueTask<TResult>后缀。

但是它不是行为良好的异步方法。异步方法应立即返回不完整的Task,从而允许调用方异步地await任务而不会被阻塞。从docs

基于TAP的异步方法可以在返回结果任务之前,同步执行少量工作,例如验证参数和启动异步操作。同步工作应保持在最低限度,以便异步方法可以快速返回。

ComplexOperation方法的作用恰恰相反:它强制调用线程执行复杂的操作,最后将已完成的任务交还给您。出于所有目的和目的,此操作完全不是异步的。它是100%同步和0%异步,外加一些开销(以增加对侮辱的伤害)。因此,请不要执行此操作,并且如果有某个库可以执行此操作,请不要使用该库。这简直是​​不好的做法。


Clarification:由于术语[[asynchronous method在不同的上下文中可能表示不同的事物,因此我应该澄清一下,此答案的上下文是消费者的观点,消费者将方法的签名视为合同,并基于可见的合同而不是基于不可见的实施来建立期望。在这种情况下,方法ComplexOperation是异步的。如果我们切换角度并专注于实现,则方法ComplexOperation不是异步的。我的声明«这简直是不好的做法»是指打破契约,并为具有异步契约的方法提供同步实现的实践。我并不是在批评使用Task.FromResult方法本身。我仅在它遵循复杂/冗长/潜在的操作时才批评它,根据该方法的约定应该使它异步。

P.S。我感谢@DmytroMukalov(在chat中)提供了按合同和按实现异步之间的有用区分。
© www.soinside.com 2019 - 2024. All rights reserved.