线程化.startnew()和.wait()
本文关键字:wait 线程 startnew | 更新日期: 2023-09-27 18:09:30
我甚至不假装理解c#中的线程,所以我正在寻找一个关于线程的真正简单的解释-更具体地说是。net 4中的StartNew()特性。
我使用下面的代码以一种即发即弃的方式调用另一个方法。当网页需要启动一个耗时的过程,但页面并不真正需要等待结果时,我可能会这样做。据我所知,DoSomething()方法将"异步"运行。"
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
DoSomething();
});
上面的代码似乎像我想要的那样工作——尽管我有一种偷偷摸摸的怀疑,我并没有真正地将它用于预期的目的。我也曾在DoSomething()方法运行之前关闭的控制台应用程序中使用过它。我不确定为什么它在网页上工作,而不是控制台应用程序-我假设是因为应用程序池继续运行,即使页面已经卸载。
真正让我困惑的是,我见过很多例子,他们以。wait()结束这样的代码。正如我所理解的,.Wait()意味着该页面上的其余代码将等待,直到DoSomething()方法运行…在这种情况下-在我有限的理解-这似乎否定了使用StartNew()的任何好处放在首位?
我希望有人能帮助解释这个方式在我简单的小头脑将理解!也许您还可以解释使用即发即弃方法调用方法的更好方法?很多谢谢!
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
DoSomething();
})
这实际上会将工作卸载到ThreadPool上。一旦一个ThreadPool
线程可用,就使用它(这意味着,如果ThreadPool被填满,它实际上可以在不同的时间执行)。
通过在最后调用.Wait()
,这将阻塞直到该任务完成执行。本质上,它不会让主线程运行,直到它完成,并且可能导致性能问题,这取决于DoSomething()
执行所需的时间。
一个更好的方法是使用async/await
,这样你的应用程序可以继续响应,而不占用主Thread
。
还要注意,您应该使用Task.Run
而不是StartNew
。除非您需要提供其他参数(如取消令牌、调度等),否则Task.Run
是默认用法。
:
// fire and forget, this will run on a thread once one is available on the thread pool
Task.Run(()=>
{
DoSomething();
});
// fire and wait until exeuction has finished. this will block all activity until it is done
Task.Run(()=>
{
DoSomething();
}).Wait();
// fire and and wait until the task is completed but do not block the current thread.
private async void DoSomethingAsync()
{
await Task.Run(()=>
{
DoSomething();
});
// perform work after
}
注意:正如VMAtm所指出的,"在ASP中启动一个任务。. NET应用程序可能是危险的,因为它可以被IIS本身的线程挂起"。
为什么危险?
- 与请求无关的线程中未处理的异常将会记下这个过程。
- 如果你在Web Farm中运行你的站点,你可能会以你的应用程序的多个实例而告终,它们都试图在同一时间运行相同的任务。
- 你的网站运行的AppDomain可能会因为一些原因而宕机,并导致你的后台任务下线。
更多信息:http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/
如何在ASP上运行任务。. NET app: http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx