2016-03-02 23 views
1

我有一個線程可以拍攝事件以在特定時間運行程序。MVC 5 - IIS停止任務線程

我確實希望網站能夠完全控制流程,這就是爲什麼我將它作爲循環的長期線程構建到網站中的原因。

問題是我安排了一個任務發生在一個特定的時間,它幾乎隨機發生(也許當我加載頁面)。看起來好像這個網絡應用程序睡眠所有的線程,直到它被使用或什麼。

下面是代碼:

public void run() 
{ 
    Task.Factory.StartNew(() => 
    { 
     while (true) 
     { 
      var lastDate = InternalEventLogger.GetLastDateTime(); 
      if (DateTime.Now >= lastDate.AddDays(1)) 
      { 
       System.Diagnostics.Debug.WriteLine(DateTime.Now); 
       System.Diagnostics.Debug.WriteLine(lastDate.AddDays(1)); 
       InternalEventLogger.RefreshLog(); 
      } 
      bool needUpdate = false; 
      System.Diagnostics.Debug.WriteLine("this"); 
      List<Event> tempList = new List<Event>(this.evtList.getList()); 
      foreach (Event evt in this.evtList.getList()) 
      { 
       if (!evt.status.Equals("success")) 
        continue; 
       if (evt.nextRun <= DateTime.Now) 
       { 
        var tempEvt = evt; 
        System.Diagnostics.Debug.WriteLine("time to run: "+evt.name); 
        tempList.Remove(evt); 
        tempEvt.nextRun = evt.nextRun.AddMinutes(evt.interval); 
        tempEvt.lastRan = DateTime.Now; 
        tempList.Add(tempEvt); 
        needUpdate = true; 
        if (tempEvt.runLocation != null) 
        Task.Factory.StartNew(() => 
        { 
         Process p = new Process(); 
         p.StartInfo.FileName = tempEvt.runLocation; 
         p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
         p.Start(); 
         string output = p.StandardOutput.ReadToEnd(); 
         string err = p.StandardError.ReadToEnd(); 
         InternalEventLogger.WriteLog(output); 
         InternalEventLogger.WriteLog("// ------------- ERROR -------------- \n" + err); 
         p.WaitForExit(); 
        }); 
       } 
      } 
      if (needUpdate) 
      { 
       this.evtList.setList(tempList); 
       this.evtList.serialize(ConfigurationManager.AppSettings["xmlEventLocation"]); 
      } 
      Thread.Sleep(10000); 
     } 
    }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); 
} 

冉從:

private static void RegisterServices(IKernel kernel) 
{ 
    evtManager = new EventManager(ConfigurationManager.AppSettings["xmlEventLocation"]); 
    evtManager.run(); 
    // Initalize Event Logger 
    new InternalEventLogger(); 
} 

這裏是一個PIC表示在定時問題:下面
enter image description here

IIS設置僅在訪問是否啓動任務。

enter image description here

+0

默認情況下IIS每隔1740分鐘(29小時)回收應用程序池http://stackoverflow.com/questions/13386471/fixing-slow-initial-load-for-iis這可能是您的問題的原因?如果是這樣,您可以在應用程序池回收設置中更改此設置:http://weblogs.asp.net/owscott/why-is-the-iis-default-app-pool-recycle-set-to-1740-minutes – user1666620

回答

0

打開,在你的IIS管理器設置對話框。 請確保您有:

  1. 啓動模式= AlwaysRunning
  2. 空閒超時(分鐘)= 0

您正在使用的應用程序池 - 測試設置,讓你相信你正在編輯正確的池。

如果你有這個,你的應用程序應該一直運行,但還有一件事 - 回收 - 在該設置對話框的底部,根據需要設置回收。您可能會遇到缺省情況,但如果您不知道回收,它可能會讓您感到驚訝,因此請確保您瞭解它並根據需要配置設置。

+0

禁用回收工作,但這可能不是最好的做法,但現在這是最簡單的方法。謝謝 –

0

是的,你是對的,IIS託管不存儲線程,因爲所有的Web應用程序必須做的是句柄的請求並提供響應。如果您想按計劃運行該任務,則確實不應該使用該Web應用程序,因爲它會在發送響應之後取消所有後臺線程。

我建議你改變你的架構,並創建一個Windows服務(如守護進程),它將在系統啓動後自動啓動,並且可以更容易地控制事件觸發。

如果由於某種原因需要這種方法的Web界面,您可以在您的Web應用程序和Windows服務之間使用一個WCF綁定(通過TCP/IP或命名管道或其他),但是您的方法不適用於Web應用程序。

我還想指出的是,這樣的代碼:

while (true) 

是一個壞主意 - 你應該使用CancellationToken在這種情況下,你的任務。

+0

你對用戶請求運行一個程序使用線程和使用像http://taskscheduler.codeplex.com/ –

+0

這樣的api鏈接到Windows任務調度程序的建議是什麼?你可以使用類似於 – VMAtm