2013-09-26 56 views
0

我正在使用Asp.net MVC 4,并且我试图在用户单击页面上的链接时在后台运行一个函数。异步运行MVC控制器中的长时间运行功能

我已经搜索和搜索,我不知道该怎么做。

我试图运行的函数是PhoneNumbersController里面的一个函数,它不返回任何东西,它只是做了很多工作。

基本上用户输入一个电话号码列表(非常大量的数字),然后点击去。

服务器会将所有这些电话号码保存到数据库中。然后我想要服务器运行类似于此的功能:

Foo(int accountId) 
    { 
     var account = GetAccountById(accountId); 

     while (account.IsRunning) 
     { 
      var Number = (from n in account.PhoneNumbers 
          where n.Status = "new" 
          select n).FirstOrDefault(); 
      // Do some work on Number. 

      Thread.Sleep(1000); // I'm working with an API that limits you to 1 per second. 

      account = GetAccountById(accountId); 
     } 
    } 

我知道,该代码是可怕的,但它只是为了显示一个示例。

我将会运行可能至少有100,000个数字,所以我们必须能够暂停和恢复这个(因此while(IsRunning)变量。我有一个暂停函数,将该值设置为false 。

正如有人谁绝不会与异步请求或者多线程工作之前,这将是最好的选择在这里,我将如何去它

在此先感谢

+0

你看过异步/等待? – christiandev

+0

我已经看过它,但在这一点上它已经超出了我的头。在我的脑海中,我觉得应该有一种方法来说“在后台异步运行这个函数”,而且看起来并不是这样。 –

+0

使用异步,你可以添加多线程电源到一个请求,但每次异步都会在你返回响应的时候完成 – Kristof

回答

1

编辑:?!阅读下面的评论,这个解决方案似乎只适用于s园艺任务,因为应用程序池可能会杀死创建的线程

你可以简单地创建一个后台线程:

var t = new System.Threading.Thread(() => Foo(yourAccountId)) {IsBackground= true}; 

并运行它:

t.Start(); 
+0

如果ASP.net不在服务页面的中间,ASP.net是否会回收应用程序池?我不认为这会起作用,因为他的线程会在没有任何警告的情况下被杀死,如果发生了循环操作。 –

+0

每当我尝试这样的事情时,我都会遇到语法错误,但这次我没有得到一个。哈哈我现在正在尝试它。谢谢! –

+1

@CharliePugh我会等待确认或反对我的担忧。它现在可能正在工作,但是当IIS决定在处理过程中回收您的应用程序池时,您可能会看到“随机”错误。几乎[每个问题都询问这个问题](http://stackoverflow.com/search?q=ASP+long+running)答案是“*不要在你的ASP.net应用程序中执行长时间运行的过程,外部服务执行长时间运行的操作并使用某种形式的IPC在它们之间进行通信(如[WCF](http://msdn.microsoft.com/zh-cn/library/ms731082.aspx))*“ –

0

在我看来它不会nessecary产卵一个ASP.NET网站中的新线程。每个客户端请求都在ISS的一个线程中处理。

但是,如果这个过程真的要花费太多的时间离开网络服务器,我怀疑。你总是可以将真正的工作委托给另一个系统。

+0

是的,但如果你不希望你的浏览器挂起,而服务器正在处理非常非常长的请求,创建一个线程是一个选项 – Kek

+1

没有浏览器将永远不得不等待,直到服务器返回响应。在服务器上产生一个新线程将不会解决此问题 – Dbuggy

+0

为什么不能。线程生成了,然后控制器返回一个响应,并且当线程仍在服务器上运行时,浏览器显示页面 – Kek