Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.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# 非并行运行的异步方法_C#_Asp.net_.net_Asp.net Mvc_Asp.net Mvc 4 - Fatal编程技术网

C# 非并行运行的异步方法

C# 非并行运行的异步方法,c#,asp.net,.net,asp.net-mvc,asp.net-mvc-4,C#,Asp.net,.net,Asp.net Mvc,Asp.net Mvc 4,我正在尝试理解async/Wait,看看是否需要在我的ASP.NETMVC5应用程序中使用异步调用 使用值填充视图模型时,我有以下几点: MyViewModel myViewModel = new MyViewModel(); myViewModel.Answer1 = await myService.CalculateAnswer1Async(); myViewModel.Answer2 = await myService.CalculateAnswer2Async(); 以及上述两种方法背

我正在尝试理解async/Wait,看看是否需要在我的
ASP.NETMVC5
应用程序中使用异步调用

使用值填充视图模型时,我有以下几点:

MyViewModel myViewModel = new MyViewModel();
myViewModel.Answer1 = await myService.CalculateAnswer1Async();
myViewModel.Answer2 = await myService.CalculateAnswer2Async();
以及上述两种方法背后的代码:

public async Task<int> CalculateAnswer1Async()
{
     await Task.Delay(5000);

     return 111;
}

public async Task<int> CalculateAnswer2Async()
{
     await Task.Delay(6000);

     return 222;
}
public async Task calculateanswerasync()
{
等待任务。延迟(5000);
返回111;
}
公共异步任务CalculateAnswer2Async()
{
等待任务。延迟(6000);
返回222;
}
据我所知,上述两个方法将依次执行,首先是
CalculateAnswer1Async()
,然后是
CalculateAnswer2Async()
。因此,完成此操作所需的最长时间应该是6秒左右(CalculateAnswer2Async()完成所需的时间)?但当我运行页面时,加载大约需要11秒,即5秒+6秒=11秒

有人能帮我澄清一下我做错了什么吗

myViewModel.Answer1 = await myService.CalculateAnswer1Async();
这将阻止当前线程,直到myService.CalculateAnswer1Async()完成。 事实上,当你使用wait关键字时,你是在告诉正在执行的线程:“嘿,wait unitl,我完成了这个操作,然后你就可以自由地执行下一行代码了。”

编辑:
而myService.calculateAnswerAsync();当myService.CalculateAnswer1Async()完成工作时,主线程可以返回到调用的某个对象。它将返回并转到方法的其余部分。

在第一个方法完成后,您将启动第二个方法
CalculateAnswer2Async
,因为您等待第一个方法的结果

立即等待异步操作的结果只有在UI线程中才真正有用,因为它释放UI线程来做其他工作,而不是阻塞它。但它不会引入并发性

您要做的是先启动第一个方法,然后启动第二个方法,然后对两个结果调用
wait

var result1 = myService.CalculateAnswer1Async();
var result2 = myService.CalculateAnswer2Async();
myViewModel.Answer1 = await result1;
myViewModel.Answer2 = await result2;


async
/
await
本身并不引入并发性,而且完全有可能所有代码都同步运行。但是使用
async
await
可以让您从异步调用中获益,同时仍然拥有易于编写的代码,并且其行为与同步版本中的预期基本相同。

在这种情况下,await会阻止方法的执行,直到异步方法完成为止,一个接一个地有效地运行它们

实际上,您要做的是并行运行它们:

MyViewModel myViewModel = new MyViewModel();
Task<int>[] tasks = new []
{
   myService.CalculateAnswer1Async();
   myService.CalculateAnswer2Async();
};

Task.WaitAll(tasks);

myViewModel.Answer1 = tasks[0].Result;
myViewModel.Answer2 = tasks[1].Result;
MyViewModel MyViewModel=newmyviewmodel();
任务[]任务=新任务[]
{
myService.CalculateAnswer1Async();
myService.CalculateAnswer2Async();
};
Task.WaitAll(任务);
myViewModel.Answer1=任务[0]。结果;
myViewModel.Answer2=任务[1]。结果;

当您等待时,您将暂停当前的
异步
方法,直到该操作完成。线程被释放以执行其他工作,但该方法将不会继续执行,直到
wait
完成。我在我的博客上有一个更详细的描述

如果要同时执行多个异步请求,则可以延迟
等待
,直到所有任务都已启动。所以这是一个选择:

MyViewModel myViewModel = new MyViewModel();
var task1 = myService.CalculateAnswer1Async();
var task2 = myService.CalculateAnswer2Async();
myViewModel.Answer1 = await task1;
myViewModel.Answer2 = await task2;
使用
任务稍微有效一些。当所有的
(通常会产生clearar/cleaner代码):

如果所有操作都返回相同类型的值(
int
,在本例中),则可以使用
任务的结果来避免“虚假等待”。whalll

MyViewModel myViewModel = new MyViewModel();
var task1 = myService.CalculateAnswer1Async();
var task2 = myService.CalculateAnswer2Async();
var results = await Task.WhenAll(task1, task2);
myViewModel.Answer1 = results[0];
myViewModel.Answer2 = results[1];

如何将其更改为异步运行?它不会真正阻止当前线程,但您所使用的方法的可观察效果非常相似。它已异步运行,但恐怕您不知道并行编程和异步编程之间的区别。常规异步编程的最大区别在于,当您使用wait时,它不会阻塞当前线程,而只是命令等待。您似乎认为wait启动了一个新线程。情况正好相反:它等待现有的计算完成。
MyViewModel myViewModel = new MyViewModel();
var task1 = myService.CalculateAnswer1Async();
var task2 = myService.CalculateAnswer2Async();
var results = await Task.WhenAll(task1, task2);
myViewModel.Answer1 = results[0];
myViewModel.Answer2 = results[1];