我有一个简单的方法,可以执行复杂的字符串操作并返回结果。如您所见,此方法的返回类型为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完成返回),此方法会异步运行吗?
根据您的评论,您需要执行以下操作:
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中也没有多大意义。
就像您将Main方法标记为异步以获取异步方法一样,您需要使用async关键字将该方法标记为异步,并将结果设为Task。
但是在框架中,任务用于2个相关但不同的概念,并行化和异步编程。
您正在做的是使用并行化。
所以您只是在其他线程上运行一些同步代码。
根据您的示例,我认为您需要使用并行化,这可以加快一些复杂的计算速度,或者通过使用多个线程来并行工作。
异步代码背后的概念是在等待外部资源(例如来自Web服务的某些数据)时释放线程,以允许同时进行其他工作。
因此,如果需要使用本地资源进行复杂的工作,最好使用没有异步逻辑的任务,而当使用远程资源时,可以进行异步操作。
语义上,方法ComplexOperation
是异步的,因为它返回一个可等待的类型,并且为了跟随the guidelines,应将其命名为ComplexOperationAsync
。
在TAP中,异步方法在返回可等待类型(例如
Async
,Task
,Task<TResult>
和ValueTask
等类型的方法的操作名称后包含ValueTask<TResult>
后缀。
但是它不是行为良好的异步方法。异步方法应立即返回不完整的Task
,从而允许调用方异步地await
任务而不会被阻塞。从docs:
基于TAP的异步方法可以在返回结果任务之前,同步执行少量工作,例如验证参数和启动异步操作。同步工作应保持在最低限度,以便异步方法可以快速返回。
ComplexOperation
方法的作用恰恰相反:它强制调用线程执行复杂的操作,最后将已完成的任务交还给您。出于所有目的和目的,此操作完全不是异步的。它是100%同步和0%异步,外加一些开销(以增加对侮辱的伤害)。因此,请不要执行此操作,并且如果有某个库可以执行此操作,请不要使用该库。这简直是不好的做法。
Clarification:由于术语[[asynchronous method在不同的上下文中可能表示不同的事物,因此我应该澄清一下,此答案的上下文是消费者的观点,消费者将方法的签名视为合同,并基于可见的合同而不是基于不可见的实施来建立期望。在这种情况下,方法ComplexOperation
是异步的。如果我们切换角度并专注于实现,则方法ComplexOperation
不是异步的。我的声明«这简直是不好的做法»是指打破契约,并为具有异步契约的方法提供同步实现的实践。我并不是在批评使用Task.FromResult
方法本身。我仅在它遵循复杂/冗长/潜在的操作时才批评它,根据该方法的约定应该使它异步。