所以我被告知我在这里做的事情是错的,但我不确定为什么。
我有一个网页,用于导入带有文档编号的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();
}
}
(显然有一些错误检查和用户投掷的消息)
所以我的三个问题是:
答案 0 :(得分:8)
可能的问题是您的后台线程正在您的网站应用程序池中运行。 IIS可能决定回收您的应用程序池,导致昂贵的操作在完成之前被杀死。
我宁愿选择一个选项,我有一个单独的进程,可能是一个Windows服务,它将获得昂贵的操作请求并在asp.net进程外执行它们。这不仅意味着您的昂贵操作将在应用程序池重新启动后继续存在,而且还会简化您的Web应用程序,因为它不必处理处理。
告诉服务执行昂贵的过程可以使用某种进程间通信来完成,服务可以轮询数据库表或文件,或者您可以使用服务将侦听的管理队列。
有很多方法可以做到这一点,但我的主要观点是,如果可能,您应该将昂贵的流程与Web应用程序分开。
答案 1 :(得分:7)
我建议您使用BackgroundWorker类而不是直接使用线程。这是因为BackgroundWorker
专门用于为图形应用程序执行后台操作,并且(除其他外)提供了将更新传达给用户界面的机制。
答案 2 :(得分:1)
a:是的。
使用ThreadPool;)对WorkItem进行排队 - 避免产生大量线程的开销。