2015-11-07 67 views
0

我想從自己的AppDomain下面開始潛在的長時間運行線程,以防止Web服務器在回收期間中止它。它編譯罰款,但在運行時我得到這個神祕的錯誤在AppDomain中創建與AppDomain相同的新AppDomain調用方法

類型未解決的成員「MyCore.MyWebService,MyCore, 版本= 5.0.0.0,文化=中立,公鑰=空」。

如何找出哪些成員沒有解決?

有沒有更好的方法在MVC業務服務層中運行長久的線程,但不會因服務器回收機制而中止?

下面是代碼:

namespace MyCore 
{ 
    [Serializable] 
    public class MyWebService : IMyWebService 
    { 
     AppDomain domain = AppDomain.CreateDomain("Domain"); 
     Thread.CurrentThread.Name = "MVCThread"; 
     domain.SetData("lDatabaseID", lDatabaseID); 

     domain.DoCallBack(() => 
     { 
     long lID = Convert.ToInt64(AppDomain.CurrentDomain.GetData("lDatabaseID")); 
     Thread thread = new Thread(
     (() => 
     { 
      PopulateTables(lID); 
     })); 
     thread.Name = "DomThread"; 
     thread.Start(); 
    }); 
    } 
} 
+1

是什麼讓你認爲在新的AppDomain中啓動一個線程會阻止IIS回收你的ASP.NET應用程序和整個w3p關聯的進程?您可以簡單地忘記在IIS中的後臺線程上執行可靠的長時間運行任務。這不是Web服務器的設計目的。 –

+0

你是對的,我捅了一下,可能已經找到了使用Hangfire的解決方案。 – aggaton

回答

0

好吧,我終於得到它在.NET 4.0中的工作和MVC 3,必須安裝Common.Logging.Core 2.2.0,因爲安裝的NuGet錯誤的版本(3.3。0)

以我初始控制器I加入下列

namespace Core.Controllers 
{ 
... 
    public void Configuration(IAppBuilder app) 
    { 
    app.UseHangfire(config => 
    { 
     config.UseSqlServerStorage(ConnectionString.GetTVConnectionString()); 
     config.UseServer(); 
    }); 
    } 
... 
} 

ConnectionString.GetTVConnectionString()獲取從配置文件中的連接字符串。

往上頂我增加了以下

[assembly: OwinStartup(typeof(Core.Controllers.BaseController))] 

在啓動後臺線程我添加以下代碼,傳入一個長期而不是類和具有工作從數據庫加載POCO類。

BackgroundJob.Enqueue(() => PopulateTables(lDatabaseID, JobCancellationToken.Null)); 

入列()函數返回一個任務ID,以後可用於如果需要取消的作業,通過BackgroundJob.Delete(作業ID)的功能。

在作業方法,然後我有這個

while (idxMin < max) 
{ 
    try 
    { 
     cancellationToken.ThrowIfCancellationRequested(); 
     .... 
    } 
    catch (JobAbortedException jobEx) 
    { 
     .... 
    } 
} 

使用依賴注入是很重要的,所以我班有一個參數的構造函數補充說,重新讀取連接字符串,而不是有它的通過。

public MyWebService() 
     : this(ConnectionString.GetTVConnectionString()) 
{ 
} 

public MyWebService (string sConnStr) 
{ 
    msConnStr = sConnStr; 
} 

之後,它似乎運行得很好。許多表被添加到連接字符串中指定的數據庫中。到目前爲止,似乎這些工作能在網絡服務器上回收利用。

1

IIS在很大程度上優化,速度非常快,以幾百個小同時請求的迴應,只是不是你嘗試什麼樣的工具。你可以嘗試解決這個問題,但從長遠來看,建立一個專爲長期運行任務而設計的工具會更好。下一次出現此問題時,您已經獲得了預先打包的解決方案。

基本的想法是創建一個外部應用程序,通過某種方式執行後臺處理,將任務傳遞給它並返回結果。我喜歡使用數據庫進行通信,因爲大多數需要baground處理的web應用程序已經使用數據庫。使用{status,startedDateTime,finishedDateTime,parameters等}添加一個'tasks'表,然後編寫一個外部應用程序,它定期查找一個新任務,完成它並更新數據庫。您的網站可以輪詢數據庫的狀態,或者您的應用程序可以通過AJAX調用在作業完成時通知網站(網站標題中的小型iframe顯示等待/已完成的任務可能會有用,如果有人等待爲了完成這項工作並且很容易做到)。

編輯:之前,你做上述審查HangFire(它在IIS中作爲Windows服務或作爲控制檯應用程序工作)。相同的原則,但預先打包的解決方案。請注意,我還沒有實現,但它看起來不錯。

雖然這是一個工作位的設置,交給這個任務開了一個Windows服務是一個很好的方法,如果你可能有多個任務,需要的時候快速響應。有很多在網絡上的教程,這將有助於您創建一個Windows服務,如http://www.codeproject.com/Articles/106742/Creating-a-simple-Windows-Service但你必須建立在最重要的是一個簡單的任務執行,所以如果這是你想要去我會找路一個預先構建的任務引擎(我無法快速找到一個,但我可能使用了錯誤的搜索短語)。

但是,這是矯枉過正,如果週轉時間並不重要,你一個更好的方法是創建一個將被任務調度器每五分鐘開始了小控制檯應用程序。它會連接到數據庫,執行任何等待任務,然後再次關閉。這比Windows服務更易於調試和安裝,並實現將任務執行從IIS移出的相同目標。

請記住,你仍然有檢測和處理Windows關機,這樣你就不會得到半成品孤立的工作 - 至少是隻標記該任務爲中止和退出乾淨。與遲髮型已經打亂後

+0

感謝您的回答,我多花點時間,並可能在Hangfire中找到了解決方案。 – aggaton

+0

感謝您的提及。 HangFire對於我現在正在開發的項目來說看起來非常棒。我想我會在Windows服務中保留我的處理,但用HangFire替換我的半建任務系統。爲什麼不回答你自己的問題?我認爲HangFire在這裏是正確的答案。 – christutty

+0

好吧,我一整天都在努力讓Hangfire玩,我似乎無法讓它工作,也許我使用的庫和Hangfire似乎有一些要求不匹配。它使用Owin和WebHost。如果我使用NuGet安裝Hangfire,我似乎無法再啓動我的Web應用程序了。我也使用.Net 4.0和MVC 3.0(目前我沒有時間冒險升級,因爲它似乎總是一個耗時的過程)。這就是爲什麼我猶豫不決的原因。但你可能比我運氣好。 – aggaton