2

アプリケーションが System.Diagnostics クラスを使用してシステム上でコマンドを実行する Web アプリを作成しています。完了までに時間がかかるコマンドからのリアルタイム出力を表示したかったのです。少し調べたところ、BeginOutputReadLine は出力をイベント ハンドラーにストリーミングできることがわかりました。

また、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 秒ごとにアラート ボックスに「未定義」と表示されます。誰かがそれを正しく行う方法を教えてもらえますか?

4

1 に答える 1

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 にアクセスできません。したがって、セッション状態バッグは使用できません。アプリケーション キャッシュを使用することもできますが、通常、このタイプのメカニズムには使用されません (キャッシュはパフォーマンス上の理由で使用できますが、永続化メカニズムでは使用できません。Web アプリケーションがいつリサイクルされるかを制御できないことに注意してください)。

データベースまたはログ ファイルに書き込むことを強くお勧めします。一般に、非同期プロセスでは、潜在的な問題を診断し、結果を検証するために、ログに記録された出力またはトレースが必要です。

さらに、Web アプリがいつリサイクルされるかを制御できないため、起動している子プロセスの制御を簡単に失う可能性があります。より良い設計では、非同期メソッド インプロセス、またはデータベースをポーリングしてジョブを取得するプロセス外のアプリケーションまたはサービスを開始します (プラットフォームによっては、タスク スケジューラまたは cron を使用する可能性があります)。

于 2014-04-09T02:36:15.067 に答える