运行 方法在 Action 中的单独线程上
Run method on a separate thread inside Action
假设我有一个如下所示的操作,我想 return 尽快查看并继续在后台线程中做一些工作。
public async Task<ActionResult> Index()
{
Debug.WriteLine("Inside Index");
var newCustomer = new Customer
{
Name = "Ibrahim"
};
Task.Run(() => SaveCustomer(newCustomer));
Debug.WriteLine("Exiting Index");
return View();
}
private async Task SaveCustomer(Customer NewCustomer)
{
Debug.WriteLine("Started Saving Customer");
await Task.Delay(2000);
Debug.WriteLine("Completed Saving Customer");
}
我确实得到了预期的输出:
Inside Index
Exiting Index
Started Saving Customer
Completed Saving Customer
但令我困扰的是,我收到一条警告,我的 Index
操作将 运行 同步,而我应该放一个 await
但视图是 return 在 SaveCustomer
完成并且目的失败后编辑。
我怎么做错了?任何建议表示赞赏。
您的 Index
根本没有使用任何异步功能。为什么标记为async
?你一定是误会了什么,不确定是什么。删除 async Task
规范。
您收到该编译器警告是因为您的 Index()
方法中没有任何异步内容。您的 Task.Run(() => SaveCustomer(newCustomer));
行表示即发即弃(非等待任务)——这与 异步 代码非常不同。 Index()
是完全同步的,同时创建一个 "side Task" 以在将来某个时间执行。正如提到的另一个答案 - 你也可以从你的方法中删除异步标记 - 它不是异步的。
But what bothers me is that I get a warning that my Index action will run synchronously
How am I doing this wrong?
不要自上而下强制异步。相反,从最低级别 的自然异步操作开始(例如,EF6 数据库访问),并允许异步从最低级别的代码向上增长。
另外,在 ASP.NET,你应该强烈避免 Task.Run
。
应用这两个原则会产生如下 Index
方法:
public async Task<ActionResult> Index()
{
Debug.WriteLine("Inside Index");
var newCustomer = new Customer
{
Name = "Ibrahim"
};
await SaveCustomer(newCustomer);
Debug.WriteLine("Exiting Index");
return View();
}
but then the view is returned after SaveCustomer is completed and the purpose is defeated.
完全没有。异步ASP.NET代码的目的是不是到return早到客户端。 async
和 await
不更改 HTTP 协议。 await
服务器端让步给线程池,而不是客户端。
如果你需要到return早(大多数人不需要 - 他们只是认为他们“需要”到),那么你应该使用 one of the established patterns for returning early(正如我在我的博客中描述的那样)。请注意,唯一正确(即完全可靠)的解决方案需要设置一个具有独立后台进程的可靠队列。
假设我有一个如下所示的操作,我想 return 尽快查看并继续在后台线程中做一些工作。
public async Task<ActionResult> Index()
{
Debug.WriteLine("Inside Index");
var newCustomer = new Customer
{
Name = "Ibrahim"
};
Task.Run(() => SaveCustomer(newCustomer));
Debug.WriteLine("Exiting Index");
return View();
}
private async Task SaveCustomer(Customer NewCustomer)
{
Debug.WriteLine("Started Saving Customer");
await Task.Delay(2000);
Debug.WriteLine("Completed Saving Customer");
}
我确实得到了预期的输出:
Inside Index
Exiting Index
Started Saving Customer
Completed Saving Customer
但令我困扰的是,我收到一条警告,我的 Index
操作将 运行 同步,而我应该放一个 await
但视图是 return 在 SaveCustomer
完成并且目的失败后编辑。
我怎么做错了?任何建议表示赞赏。
您的 Index
根本没有使用任何异步功能。为什么标记为async
?你一定是误会了什么,不确定是什么。删除 async Task
规范。
您收到该编译器警告是因为您的 Index()
方法中没有任何异步内容。您的 Task.Run(() => SaveCustomer(newCustomer));
行表示即发即弃(非等待任务)——这与 异步 代码非常不同。 Index()
是完全同步的,同时创建一个 "side Task" 以在将来某个时间执行。正如提到的另一个答案 - 你也可以从你的方法中删除异步标记 - 它不是异步的。
But what bothers me is that I get a warning that my Index action will run synchronously
How am I doing this wrong?
不要自上而下强制异步。相反,从最低级别 的自然异步操作开始(例如,EF6 数据库访问),并允许异步从最低级别的代码向上增长。
另外,在 ASP.NET,你应该强烈避免 Task.Run
。
应用这两个原则会产生如下 Index
方法:
public async Task<ActionResult> Index()
{
Debug.WriteLine("Inside Index");
var newCustomer = new Customer
{
Name = "Ibrahim"
};
await SaveCustomer(newCustomer);
Debug.WriteLine("Exiting Index");
return View();
}
but then the view is returned after SaveCustomer is completed and the purpose is defeated.
完全没有。异步ASP.NET代码的目的是不是到return早到客户端。 async
和 await
不更改 HTTP 协议。 await
服务器端让步给线程池,而不是客户端。
如果你需要到return早(大多数人不需要 - 他们只是认为他们“需要”到),那么你应该使用 one of the established patterns for returning early(正如我在我的博客中描述的那样)。请注意,唯一正确(即完全可靠)的解决方案需要设置一个具有独立后台进程的可靠队列。