线程 .StartNew() 和 .Wait()
Threading .StartNew() and .Wait()
我什至不假装理解 C# 中的线程,所以我正在寻找关于线程的真正简单的解释 - 更具体地说是 .NET 4 中的 StartNew() 功能。
我使用以下代码以一种即发即弃的方法调用另一个方法。当网页需要启动一个耗时的过程,但页面并不真正需要等待结果时,我可能会这样做。据我了解, DoSomething() 方法将 运行 "asynchronously."
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
DoSomething();
});
上面的代码似乎可以按我希望的方式运行 - 尽管我偷偷怀疑我并没有真正将它用于预期目的。在 DoSomething() 方法 运行 之前关闭的控制台应用程序中,我也被发现使用它。我不确定为什么它适用于网页但不适用于控制台应用程序 - 我假设是因为应用程序池继续 运行 即使页面已被卸载。
真正让我感到困惑的是,我见过很多这样的代码以 .Wait() 结尾的例子。据我了解,.Wait() 意味着此页面上的其余代码将等到 DoSomething() 方法具有 运行... 在这种情况下 - 在我有限的理解中 - 这似乎否定了首先使用 StartNew() 有什么好处?
我希望有人能以我简单的小头脑能理解的方式帮助解释这一点!也许您还可以解释一种更好的调用方法的方法,即用即弃方法?非常感谢!
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
DoSomething();
})
这实际上会将工作卸载到 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 本身 与线程挂起”。
为什么危险?
- 与请求无关的线程中未处理的异常将
记下这个过程。
- 如果您 运行 您的站点位于网络场中,您最终可能会得到应用程序的多个实例,它们都会同时尝试 运行 同一任务。
- 您的站点 运行 所在的 AppDomain 可能会因多种原因而关闭并取消您的后台任务
有了它。
如何在 ASP.NET 应用上 运行 任务:http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx
我什至不假装理解 C# 中的线程,所以我正在寻找关于线程的真正简单的解释 - 更具体地说是 .NET 4 中的 StartNew() 功能。
我使用以下代码以一种即发即弃的方法调用另一个方法。当网页需要启动一个耗时的过程,但页面并不真正需要等待结果时,我可能会这样做。据我了解, DoSomething() 方法将 运行 "asynchronously."
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
DoSomething();
});
上面的代码似乎可以按我希望的方式运行 - 尽管我偷偷怀疑我并没有真正将它用于预期目的。在 DoSomething() 方法 运行 之前关闭的控制台应用程序中,我也被发现使用它。我不确定为什么它适用于网页但不适用于控制台应用程序 - 我假设是因为应用程序池继续 运行 即使页面已被卸载。
真正让我感到困惑的是,我见过很多这样的代码以 .Wait() 结尾的例子。据我了解,.Wait() 意味着此页面上的其余代码将等到 DoSomething() 方法具有 运行... 在这种情况下 - 在我有限的理解中 - 这似乎否定了首先使用 StartNew() 有什么好处?
我希望有人能以我简单的小头脑能理解的方式帮助解释这一点!也许您还可以解释一种更好的调用方法的方法,即用即弃方法?非常感谢!
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
DoSomething();
})
这实际上会将工作卸载到 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 本身 与线程挂起”。
为什么危险?
- 与请求无关的线程中未处理的异常将 记下这个过程。
- 如果您 运行 您的站点位于网络场中,您最终可能会得到应用程序的多个实例,它们都会同时尝试 运行 同一任务。
- 您的站点 运行 所在的 AppDomain 可能会因多种原因而关闭并取消您的后台任务 有了它。
如何在 ASP.NET 应用上 运行 任务:http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx