【问题标题】:Threading .StartNew() and .Wait()线程化 .StartNew() 和 .Wait()
【发布时间】:2016-09-29 23:22:54
【问题描述】:

我什至不假装理解 C# 中的线程,所以我正在寻找一个关于线程的非常简单的解释 - 更具体地说是 .NET 4 中的 StartNew() 功能。

我使用以下方法调用另一种方法,使用一种即发即弃的方法。当网页需要启动一个耗时的过程,但页面并不真正需要等待结果时,我可能会这样做。据我了解,DoSomething() 方法将“异步”运行。

System.Threading.Tasks.Task.Factory.StartNew(() =>
{
    DoSomething();
});

上面的代码似乎可以按我的意愿工作——尽管我有一个偷偷摸摸的怀疑,我并没有真正将它用于它的预期目的。我还在 DoSomething() 方法运行之前关闭的控制台应用程序中使用它。我不确定为什么它适用于网页而不适用于控制台应用程序 - 我假设是因为即使页面已卸载,应用程序池也会继续运行。

真正让我感到困惑的是,我见过很多例子,它们以 .Wait() 结束此类代码。据我了解, .Wait() 意味着此页面上的其余代码将等到 DoSomething() 方法运行......在这种情况下 - 在我有限的理解中 - 这似乎否定了使用的任何好处首先是 StartNew()?

我希望有人能以我简单的小头脑能理解的方式帮助解释这一点!也许您还可以解释一种使用即发即弃方法调用方法的更好方法?非常感谢!

【问题讨论】:

  • 您几乎不应该在 ASP.NET 中创建线程。也可以更好地使用hangfire.io

标签: c# asp.net multithreading task wait


【解决方案1】:
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 应用上运行任务:http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx

【讨论】:

  • 您应该注意,在 ASP.NET 应用程序中启动一个任务可能很危险,因为它可以被 IIS 本身用线程挂起
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-18
  • 2015-12-15
  • 2012-04-28
  • 2021-10-11
  • 1970-01-01
相关资源
最近更新 更多