2012-10-26 40 views
2

我正在編寫一個Web應用程序,其中應用程序在使用System.Diagnostics類的系統上運行命令。 我想顯示一個需要很長時間才能完成的命令的實時輸出。搜索了一下後,我發現BeginOutputReadLine可以將輸出流傳輸到事件處理程序。在asp.net中實時顯示命令行程序的輸出

我也在使用jquery ajax來調用這個方法,並讓這個進程異步運行。 到目前爲止,我試圖做這種方式:

Process p2= new Process(); p2.OutputDataReceived += new DataReceivedEventHandler(opHandler); p2= Process.Start (psi2);
p2.BeginOutputReadLine();

我已經聲明瞭一個靜態變量,以命令的輸出保存爲網頁上的標籤一類不會是從靜態訪問方法。

public class ProcessOutput 
{ 
    public static string strOutput; 

    [WebMethod] 
    public static string getOutput() 
    { 
     return strOutput; 
    } 
} 

在BeginOutputReadLine的事件處理函數中,使用輸出中的行設置變量。

private static void opHandler(object sendingProcess,DataReceivedEventArgs outLine) 
    { 
     if (!String.IsNullOrEmpty(outLine.Data)) 
     { 
      ProcessOutput.strOutput= outLine.Data; 
     } 
    } 

和ASPX頁面,我打電話的方法來獲得strOutput

的我不知道爲什麼值
$(document).ready(function() { 

setInterval(function() { 
    $.ajax({ 
    type: "GET", 
    url: "newscan.aspx/getOutput", 
    data: "", 
    success: function(msg){ 
    $('#txtAsyncOp').append(msg.d); 
    } 
}); 
}, 1000); 

});  

,但拉布勒是不會得到更新。如果我放置警報,則每10秒在警報框中顯示「未定義」。 任何人都可以建議我如何正確地做到這一點?

+0

你能解決你的問題嗎?請告訴我;如果是的話,請標記爲已回答 - 謝謝! :) – webbexpert

回答

0

每個請求都會作爲請求管道的一部分開始一個新線程。這是設計。每個線程都有自己的堆棧,不能訪問其他堆棧。當一個線程開始運行一個新的方法時,它將自變量中的參數和局部變量存儲在自己的棧中。長話短說,您將無法分配該變量,並希望從其他請求中檢索其值。

有幾個方法,你可以,你可以用範圍,會話變量(最常見):

System.Web.HttpContext.Current.Session["variable"] = value ; 

或者你用它設置爲應用範圍:

if (System.Web.Caching.Cache["Key1"] == null) 
     System.Web.Caching.Cache.Add("Key1", "Value 1", null, DateTime.Now.AddSeconds(60), Cache.NoSlidingExpiration, CacheItemPriority.High, onRemove); 

或者,您可以將輸出記錄到數據庫或文件,並通過WebMethod回顯結果。如果您的長時間運行的進程異步運行,您將無法訪問HttpContext - 因此會話狀態包將不可用;可以使用應用程序Cache,但通常不用於此類機制(緩存可用於性能方面的原因,而不是持久性機制 - 重要的是要記住,您無法控制Web應用程序何時回收)。

我強烈建議寫入數據庫或日誌文件。異步進程通常需要記錄輸出或跟蹤來診斷潛在問題並驗證結果。

此外,由於您無法控制Web應用程序何時回收,您可能很容易失去對您啓動的子進程的控制權。一個更好的設計將啓動一個asynchronous method in-process,或者一個輪詢數據庫來提取作業的進程外應用程序或服務(可能使用任務調度程序或cron,具體取決於您的平臺)。

相關問題