Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 线程.StartNew()和.Wait())_C#_Asp.net_Multithreading_Task_Wait - Fatal编程技术网

C# 线程.StartNew()和.Wait())

C# 线程.StartNew()和.Wait()),c#,asp.net,multithreading,task,wait,C#,Asp.net,Multithreading,Task,Wait,我甚至没有假装理解C#中的线程,所以我正在寻找一个关于线程的非常简单的解释-更具体地说是.NET 4中的StartNew()特性 我使用下面的方法调用另一个方法,使用一种fire-and-forget方法。当网页需要启动一个耗时的过程时,我可能会这样做,但是网页实际上不需要等待结果。据我所知,DoSomething()方法将“异步”运行 上面的代码似乎正是我所希望的——尽管我有一种隐秘的怀疑,我并没有真正将其用于预期目的。我还被发现在DoSomething()方法运行之前关闭的控制台应用程序中使

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

我使用下面的方法调用另一个方法,使用一种fire-and-forget方法。当网页需要启动一个耗时的过程时,我可能会这样做,但是网页实际上不需要等待结果。据我所知,DoSomething()方法将“异步”运行

上面的代码似乎正是我所希望的——尽管我有一种隐秘的怀疑,我并没有真正将其用于预期目的。我还被发现在DoSomething()方法运行之前关闭的控制台应用程序中使用它。我不知道为什么它可以在网页上运行,但不能在控制台应用程序上运行——我假设是因为应用程序池即使在页面卸载后也会继续运行

真正让我困惑的是,我已经看到了很多例子,它们以.Wait()结束这些代码。据我所知,.Wait()意味着此页面上的其余代码将等待DoSomething()方法运行。。。在这种情况下——以我有限的理解——这似乎否定了使用StartNew()的任何好处

我希望有人能帮我解释这件事,让我的头脑明白!也许您还可以解释一种更好的方法,用fire-and-forget方法调用方法?非常感谢

System.Threading.Tasks.Task.Factory.StartNew(() =>
{
    DoSomething();
})
这实际上将把工作转移到线程池上。一个
ThreadPool
线程一旦可用就会被使用(这意味着,如果线程池被填满,它实际上可以在不同的时间执行)

通过在最后调用
.Wait()
,这将阻止该任务,直到该任务完成执行。基本上,它不会让主线程运行,直到它完成, 并且可能会导致性能问题,具体取决于执行DoSomething()所需的时间

更好的方法是使用
async/await
,这样应用程序就可以继续响应,而无需占用主
线程

还请注意,您应该使用
任务。运行
而不是
开始新建
。除非您需要提供其他参数(如取消令牌、计划等),
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场中运行站点,您可能会得到多个应用程序实例,这些实例都试图同时运行同一任务
  • 您的站点运行的AppDomain可能由于多种原因而停止运行,并停止您的后台任务 用它
更多信息:


如何在ASP.NET应用程序上运行任务:

您几乎不应该在ASP.NET中创建线程。另外,为了更好地使用fire and forget,您应该注意,在ASP.NET应用程序中启动任务可能会很危险,因为IIS本身可能会使用线程挂起该任务
// 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
}