Vb.net 一个控制器中的多任务

Vb.net 一个控制器中的多任务,vb.net,multithreading,async-await,task,Vb.net,Multithreading,Async Await,Task,我有一个MVC控制器动作,它不需要n个步骤 像 Public ActionResult Index() { GetDatFromTabelCustomer() GetDataFromWebApi() GetDataFromSession() GetyetAnotherData() SendItToView() } 我打算用任务包装每个方法。运行 然后在我处理之前执行Task.WhenAll(),然后执行senditoview(),但是有很多关于为什么不应该使用Task.Run的博客 而不是异步

我有一个MVC控制器动作,它不需要n个步骤 像

Public ActionResult Index()
{
GetDatFromTabelCustomer()
GetDataFromWebApi()
GetDataFromSession()
GetyetAnotherData()
SendItToView()
}
我打算用
任务包装每个方法。运行

然后在我处理之前执行
Task.WhenAll()
,然后执行
senditoview()
,但是有很多关于为什么不应该使用Task.Run的博客 而不是异步等待,在这个场景中,我真的想运行并行任务,而不是以串行方式对每个任务进行等待, 在这样做的过程中,从线程池中缝合和撕下线程会有一些成本,但除了执行任务,我还有什么其他选择呢

示例

Public ActionResult Index()
{
Task taska=Task.Run(()=>GetDatFromTabelCustomer())
Task taskb=Task.Run(()=>GetDataFromWebApi())
Task taskc=Task.Run(()=>GetDataFromSession())
Task taskd=Task.Run(()=>GetyetAnotherData())
等待任务A;
等待任务b;
等待任务c;
等待任务;
字符串get resultA=taska.Result
.
.
.
SendItToView()
}
正确的方法是将函数重新写入异步,而不是重新写入异步。对于不公开异步API的函数,可以使用Task.Run()。您还可以使用
Task.WhenAll(
将所有任务合并到一个可等待的任务中

public async Task<ActionResult> IndexAsync()
{
    Task<string> taska = GetDatFromTabelCustomerAsync());
    Task taskb = GetDataFromWebApiAsync());
    Task taskc = Task.Run( () =>     GetDataFromSession());
    Task taskd = Task.Run( () =>      GetyetAnotherData());

    await Task.WhenAll(taska, taskb, taskc, taskd);

    string resultA = await taska;

    SendItToView()
}
public async Task解释如何从同步MVC代码转换为异步MVC代码

正确的方法是将函数重新写入异步,而不是重新写入异步,对于不公开异步API的函数,可以使用Task.Run()。也可以使用
Task.whalll(
将所有任务合并到一个等待的任务中

public async Task<ActionResult> IndexAsync()
{
    Task<string> taska = GetDatFromTabelCustomerAsync());
    Task taskb = GetDataFromWebApiAsync());
    Task taskc = Task.Run( () =>     GetDataFromSession());
    Task taskd = Task.Run( () =>      GetyetAnotherData());

    await Task.WhenAll(taska, taskb, taskc, taskd);

    string resultA = await taska;

    SendItToView()
}

public async Task解释如何从同步MVC代码转换为异步MVC代码

这些似乎都是IO密集型操作,因此我怀疑使用Task.Run()确实不是解决问题的方法。但是,您仍然可以使用Task.WhenAll()。每个方法都必须返回一个任务,并且可能会使用异步模式来完成其工作。然后,执行以下操作:

var tasks = new List<Task>()
tasks.Add(GetDataFromTableCustomer());
tasks.Add(GetDataFromWebApi());
...
await Task.WhenAll(tasks);
var tasks=新列表()
添加(GetDataFromTableCustomer());
tasks.Add(GetDataFromWebApi());
...
等待任务。何时(任务);

另外,由于这些方法返回Task,因此最好在它们的名称后面加上Async。

这些方法似乎都是IO密集型操作,因此我怀疑使用Task.Run()确实不是解决问题的方法。但是,您仍然可以使用Task.WhenAll()。每个方法都必须返回一个任务,并且可能会使用异步模式来完成其工作。然后,执行以下操作:

var tasks = new List<Task>()
tasks.Add(GetDataFromTableCustomer());
tasks.Add(GetDataFromWebApi());
...
await Task.WhenAll(tasks);
var tasks=新列表()
添加(GetDataFromTableCustomer());
tasks.Add(GetDataFromWebApi());
...
等待任务。何时(任务);

另外,由于这些方法返回任务,最好在它们的名称后面加上Async。

您不应该使用
Task.Run
。您需要的是并发性(一次多个任务),而不是并行性(一次在不同线程上多个任务).Parallelism是并发的一种形式,但您也可以使用
Task.whalll
进行异步并发

要正确解决这个问题,首先从“叶子”开始,即实际的数据库调用、WebAPI调用等。使这些端点异步(例如,使用EF的异步查询或
HttpClient
),然后让
async
从中增长。最终,您将得到
GetDataFromTableCustomerAsync
GetDataFromWebApiAsync
方法,然后您可以在控制器方法中使用这些方法:

public async Task<ActionResult> Index()
{
  var taska = GetDataFromTableCustomerAsync();
  var taskb = GetDataFromWebApiAsync();

  // Both the db query and WebAPI calls are in progress at this point.
  // So do anything *synchronous* that you want to do.
  // For example, reading session data is not I/O-bound; it should just be done synchronously.
  var sessionData = GetDataFromSession();

  // Now, (asynchronously) wait for all the asynchronous work to complete.
  await Task.WhenAll(taska, taskb);

  // And get the results.
  var resultA = await taska;
  var resultB = await taskb;

  SendItToView();
}
公共异步任务索引()
{
var taska=GetDataFromTableCustomerAsync();
var taskb=GetDataFromWebApiAsync();
//此时,db查询和WebAPI调用都在进行中。
//所以做你想做的任何事情。
//例如,读取会话数据不受I/O限制;它应该同步完成。
var sessionData=GetDataFromSession();
//现在,(异步)等待所有异步工作完成。
等待任务。WhenAll(任务A、任务B);
//并得到结果。
var resultA=等待任务a;
var resultB=等待任务b;
senditoview();
}

您不应该使用
任务。运行
。您需要的是并发性(一次执行多个任务),而不是并行性(一次在不同线程上执行多个任务)。并行性是并发性的一种形式,但您也可以使用
任务执行异步并发。当所有

要正确解决这个问题,首先从“叶子”开始,即实际的数据库调用、WebAPI调用等。使这些端点异步(例如,使用EF的异步查询或
HttpClient
),然后让
async
从中增长。最终,您将得到
GetDataFromTableCustomerAsync
GetDataFromWebApiAsync
方法,然后您可以在控制器方法中使用这些方法:

public async Task<ActionResult> Index()
{
  var taska = GetDataFromTableCustomerAsync();
  var taskb = GetDataFromWebApiAsync();

  // Both the db query and WebAPI calls are in progress at this point.
  // So do anything *synchronous* that you want to do.
  // For example, reading session data is not I/O-bound; it should just be done synchronously.
  var sessionData = GetDataFromSession();

  // Now, (asynchronously) wait for all the asynchronous work to complete.
  await Task.WhenAll(taska, taskb);

  // And get the results.
  var resultA = await taska;
  var resultB = await taskb;

  SendItToView();
}
公共异步任务索引()
{
var taska=GetDataFromTableCustomerAsync();
var taskb=GetDataFromWebApiAsync();
//此时,db查询和WebAPI调用都在进行中。
//所以做你想做的任何事情。
//例如,读取会话数据不受I/O限制;它应该同步完成。
var sessionData=GetDataFromSession();
//现在,(异步)等待所有异步工作完成。
等待任务。WhenAll(任务A、任务B);
//并得到结果。
var resultA=等待任务a;
var resultB=等待任务b;
senditoview();
}

您的示例没有意义,在第一位代码中,
GetDatFromTabelCustomer()
没有返回任何内容,但在第二位示例中,它似乎返回了一个
字符串
您的示例没有意义,在第一位代码中,
GetDatFromTabelCustomer()
没有