C# 任务的返回类型是否足以使方法异步运行?
我有一个简单的方法,它执行复杂的字符串操作并返回结果。如您所见,此方法的返回类型为C# 任务的返回类型是否足以使方法异步运行?,c#,asynchronous,async-await,task-parallel-library,C#,Asynchronous,Async Await,Task Parallel Library,我有一个简单的方法,它执行复杂的字符串操作并返回结果。如您所见,此方法的返回类型为Task。因此,我可以使用Task.FromResult(result)返回字符串的值 公共任务ComplexOperation() { 字符串结果=//执行一些复杂的操作 返回Task.FromResult(结果); } 然后,我可以使用wait关键字调用此方法 公共静态异步任务主(字符串[]args) { var myResult=await ComplexOperation(); } 因为我正在等待Com
Task
。因此,我可以使用Task.FromResult(result)
返回字符串的值
公共任务ComplexOperation()
{
字符串结果=//执行一些复杂的操作
返回Task.FromResult(结果);
}
然后,我可以使用wait
关键字调用此方法
公共静态异步任务主(字符串[]args)
{
var myResult=await ComplexOperation();
}
因为我正在等待
CompelxOperation()
,(等待任务完成时返回)此方法是否会异步运行 根据您的评论,您需要执行以下操作:
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";
});
}
公共任务ComplexOperation()
{
返回任务。运行(()=>/*做一些复杂的事情*/);
}
你可以这样玩:
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";
});
}
公共静态异步任务Main()
{
控制台。写入线(“之前”);
var myResultTask=ComplexOperation();
Console.WriteLine(“任务创建后”);
var结果=等待myResultTask;
WriteLine(“异步等待后”);
}
公共任务ComplexOperation()
{
Console.WriteLine(“创建”);
返回任务。运行(()=>
{
控制台。写线(“在工作前”);
Thread.Sleep(500);//模拟工作;
控制台。写线(“下班后”);
返回“完成”;
});
}
并将该行为与仅返回
Task.FromResult
时切换到实现进行比较。同样,在这样的测试示例TBH中,它也没有太大意义。正如您标记为async—获取异步方法的主方法—一样,您需要使用async关键字将该方法标记为asynchronous,并使结果成为一项任务
但在框架中,任务用于两个相关但不同的概念:并行化和异步编程
您正在做的是使用并行化
所以您只是在不同的线程上运行一些同步代码
基于您的示例,我认为您需要的是使用并行化,它可以通过使用多个线程并行工作来加速一些复杂的计算或工作
异步代码背后的概念是在等待外部资源(如web服务中的一些数据)时释放线程,以允许同时完成其他工作
因此,如果您需要使用本地资源执行复杂的工作,最好使用不带异步逻辑的任务,而使用远程资源时,您可以执行异步操作。从语义上讲,ComplexOperation方法是异步的,因为它返回一个等待类型,为了遵循这一点,应该将其命名为ComplexOperationAsync TAP中的异步方法包括返回可等待类型的方法的操作名称后的
Async
后缀,例如Task
、Task
、ValueTask
、和ValueTask
但它不是一种性能良好的异步方法。异步方法应立即返回不完整的任务
,允许调用方异步等待
任务而不被阻止。从:
基于TAP的异步方法可以在返回结果任务之前同步执行少量工作,例如验证参数和启动异步操作。同步工作应保持在最小值,以便异步方法可以快速返回
ComplexOperation
方法的作用正好相反:它强制调用线程执行复杂的操作,最后它返回一个已完成的任务。出于所有意图和目的,此操作根本不是异步的。它是100%同步和0%异步的,再加上一些开销(雪上加霜)。所以不要这样做,如果有某个库可以这样做,不要使用该库。这简直是坏习惯
澄清:因为术语异步方法在不同的上下文中可能意味着不同的事情,我应该澄清,这个答案的上下文是消费者的视角,消费者将方法的签名视为合同,并基于可见的契约而不是无形的实施建立期望。在这种情况下,方法
ComplexOperation
是异步的。如果我们切换视角并关注实现,那么方法ComplexOperation
就不是异步的。我的声明“这只是一种不好的做法”指的是违反契约的做法,并为具有异步契约的方法提供同步实现。我不是在批评Task.FromResult方法本身的使用。我只是在批评它遵循一个复杂的/冗长的/潜在的操作时,根据方法的契约,它应该是异步的
另外,我感谢@DmytroMukalov(在中)提供了合同异步和实施异步之间的有益区别。。您尝试过吗?;)@Franzgleichman是的,它很有效。只是不确定它是否实际异步运行。@MatthewTrip no它不会)导致
任务。FromResult
不是异步操作)@MatthewTrip错过了//做一些复杂的事情注释。是的,您将需要TaskCompletionSource
并将您的工作卸载到另一个线程,这样它就不会阻止调用的线程。@MatthewTrip或只是Task.Run(…)
将完成此工作。@Servy在我看来,使用Task.Run
意味着创建状态机的不必要的开销,可以通过使用Task.FromResult来避免(结果)
。如果我们结合使用async
、wait
和Task.FromResult(result);
,那么代码就是异步的