背景线程是个坏主意吗?为什么?

时间:2010-05-19 20:55:44

标签: c# multithreading background

所以我被告知我在这里做的事情是错的,但我不确定为什么。

我有一个网页,用于导入带有文档编号的CSV文件,以执行昂贵的操作。我把昂贵的操作放到后台线程中,以防止它阻塞应用程序。这就是我的简要说明。

protected void ButtonUpload_Click(object sender, EventArgs e)
{
    if (FileUploadCSV.HasFile)
    {
        string fileText;
        using (var sr = new StreamReader(FileUploadCSV.FileContent))
        {
            fileText = sr.ReadToEnd();
        }

        var documentNumbers = fileText.Split(new[] {',', '\n', '\r'}, StringSplitOptions.RemoveEmptyEntries);

        ThreadStart threadStart = () => AnotherClass.ExpensiveOperation(documentNumbers);
        var thread = new Thread(threadStart) {IsBackground = true};
        thread.Start();
    }
}

(显然有一些错误检查和用户投掷的消息)

所以我的三个问题是:

  • a)这是个坏主意吗?
  • b)为什么这是一个坏主意?
  • c)你会做什么呢?

3 个答案:

答案 0 :(得分:8)

可能的问题是您的后台线程正在您的网站应用程序池中运行。 IIS可能决定回收您的应用程序池,导致昂贵的操作在完成之前被杀死。

我宁愿选择一个选项,我有一个单独的进程,可能是一个Windows服务,它将获得昂贵的操作请求并在asp.net进程外执行它们。这不仅意味着您的昂贵操作将在应用程序池重新启动后继续存在,而且还会简化您的Web应用程序,因为它不必处理处理。

告诉服务执行昂贵的过程可以使用某种进程间通信来完成,服务可以轮询数据库表或文件,或者您可以使用服务将侦听的管理队列。

有很多方法可以做到这一点,但我的主要观点是,如果可能,您应该将昂贵的流程与Web应用程序分开。

答案 1 :(得分:7)

我建议您使用BackgroundWorker类而不是直接使用线程。这是因为BackgroundWorker专门用于为图形应用程序执行后台操作,并且(除其他外)提供了将更新传达给用户界面的机制。

答案 2 :(得分:1)

a:是的。

使用ThreadPool;)对WorkItem进行排队 - 避免产生大量线程的开销。