我在ASP.NET页面上运行了一个语句,这需要很长时间(很长一段时间我的意思是100毫秒,如果我希望这个页面闪电般快,那就太长了),我不在乎只要执行它就会执行。
实现这一目标的最佳(也是最简单)方法是什么?
答案 0 :(得分:8)
最简单的方法可能是让它在线程池中执行。例如,要使这个异步:
使用System; 使用System.Threading;
class Test
{
static void ExecuteLongRunningTask()
{
Console.WriteLine("Sleeping...");
Thread.Sleep(1000);
Console.WriteLine("... done");
}
static void Main()
{
ExecuteLongRunningTask();
Console.WriteLine("Finished");
Console.ReadLine();
}
}
将Main
的第一行更改为:
ThreadPool.QueueUserWorkItem(x => ExecuteLongRunningTask());
请注意,如果您传入任何参数,它们将被捕获变量 - 在某些情况下可能会产生微妙的副作用(特别是如果您在循环中使用它)。
答案 1 :(得分:3)
如果是100毫秒,那就不要打扰了。您的用户无法检测到100毫秒的延迟。
编辑:一些解释。
如果我没记错的话,100毫秒(1/10秒)接近人类可以感知的最短时间。因此,为了讨论的目的,让我承认OP的网站用户可以感知到这100毫秒,并且值得将性能提高100毫秒。我从一开始就认为OP已经正确地将这个“长期运行”任务确定为100ms改进的潜在来源。那么,为什么我建议他忽略它?
正确处理多个线程并不容易,并且是难以追踪的错误源。为问题添加线程通常不是解决方案,而是您不能立即找到的其他问题的来源(*)。
我有机会一次学习这个困难的方法,一个只能在当时最快的8-cpu系统上重现的bug,然后只是通过无情地敲击这个东西,同时模拟一定程度的网络故障会导致网络管理员排队和拍摄,如果它发生在现实生活中。该错误最终是在Unix OS内核中处理信号,并且是一些指令的安排问题。
当然,我从未见过那么糟糕的事情,我仍然看到许多开发人员因多线程错误而被绊倒。这个问题似乎一方面要求通过线程“简单的出路”,另一方面,好处只有100毫秒。由于OP似乎没有经过良好测试的线程基础设施,在我看来忽略100毫秒更好,或者可能以其他方式提升性能。
(*)当然,在许多情况下,算法可以有利地并行执行并由在多个核上运行的多个线程执行。但这听起来并不像OP有这样的情况。
答案 2 :(得分:1)
在.NET应用程序的后台处理信息时,有一个后台工作线程非常有用。更多的背景将有助于更好地回答这个问题。
答案 3 :(得分:1)
// This is the delegate to use to execute the process asynchronously
public delegate void ExecuteBackgroundDelegate();
//
[STAThread]
static void Main(string[] args)
{
MyProcess proc = new MyProcess();
// create an instance of our execution delegate
ExecuteBackgroundDelegate asynchExec = new ExecuteBackgroundDelegate(proc.Execute);
// execute this asynchronously
asynchExec.BeginInvoke(null, null);
}
答案 4 :(得分:0)
如果您想在运行命令之前发送响应,则可以使用ThreadPool.QueueUserWorkItem在另一个线程上运行它而不会阻止您的请求。
答案 5 :(得分:0)
你可以使用ThreadPool。
ThreadPool.QueueUserWorkItem( o => Thread.Sleep(1000) /*your long task*/ );
答案 6 :(得分:0)
class Test
{
void LongRunningTask()
{
Console.WriteLine("Sleeping...");
Thread.Sleep(10000);
Console.WriteLine("... done");
}
static void Main()
{
Test t = new Test();
new Action(() => t.LongRunningTask()).BeginInvoke(null, t);
}
}
答案 7 :(得分:0)
对于延迟100ms的任何线程,我都不会费心。这样做会很好:
protected void Page_Unload(object sender, EventArgs e)
{
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.Close();
// Your code here
}
(复制自我之前的this question答案)
由于与客户端下载页面的连接将被关闭,因此他们的浏览器将停止显示加载消息。但是,您的代码将继续正常执行。