1

MVC 3 アプリケーションでオーディオ処理を行う必要があり、これらのさまざまなバックグラウンド メソッドの長所と短所を知りたいです。原則として、音声処理は長時間実行されるプロセスになるため、IIS が他の要求を自由に処理できるようにしておきたいと思います。

  1. AsyncController とバックグラウンド ワーカー

    public ActionResult GetAudioCompleted(byte[] audio)
    {
    return File(audio, "audio/wav", "mywavfile.wav");
    }
    
    public void GetAudioAsync()
    {          
        BackgroundWorker w = new BackgroundWorker();
        w.RunWorkerCompleted += (s, e) =>
        {
            AsyncManager.Parameters["audio"] = e.Result;
            AsyncManager.OutstandingOperations.Decrement();
        };
        w.DoWork += (s, e) =>
        {      
            byte[] b;       
            using (var ms = new MemoryStream())
            {
                // Process audio to memory stream
    
                ms.Seek(0, SeekOrigin.Begin);
                b = new byte[ms.Length];
                ms.Read(b, 0, (int)ms.Length);
                e.Result = b;
            }
        };
        AsyncManager.OutstandingOperations.Increment();
        w.RunWorkerAsync();            
    }
    
  2. AsyncController & タスク

    public ActionResult GetAudioCompleted(byte[] audio)
    {
        return File(audio, "audio/wav", "mywavfile.wav");
    }
    
    public void GetAudioAsync()
    {            
        AsyncManager.OutstandingOperations.Increment();
        var t = Task<byte[]>.Factory.StartNew(() =>
        {
            byte[] b;
            using (var ms = new MemoryStream())
            {
                // Process audio to memory stream
                ms.Seek(0, SeekOrigin.Begin);
                b = new byte[ms.Length];
                ms.Read(b, 0, (int)ms.Length);
            }
            return b;
        })
        .ContinueWith(c =>
            {
                AsyncManager.Parameters["audio"] = c.Result;
                AsyncManager.OutstandingOperations.Decrement();
            });          
    }
    
  3. 非非同期コントローラーとスレッド

    public ActionResult GetaAudio()
    {
        byte[] b;
    
        using (var ms = new MemoryStream())
        {
            var t = Thread(() =>
                {
                    // Process audio to memory stream
                });
            t.Start();
            t.Join();
    
            // error checking etc.
            ms.Seek(0, SeekOrigin.Begin);
            b = new byte[ms.Length];
            ms.Read(b, 0, (int)ms.Length);
            return File(b, "audio/wav", "mywavfile.wav");
        }
    }
    

質問:

  1. BackgroundWorkers は Web アプリケーションでの使用が推奨されていますか?
  2. タスクを使用する場合、このバックグラウンド スレッドは IIS スレッドプールからのものを使用しますか (スレッドが要求処理のために解放されないため、このアプローチの利点の 1 つが無効になる可能性があります)。
  3. System.Threading.Thread の使用 - このスレッドは IIS スレッドプールのいずれかを使用しますか。t.Join() は現在の IIS スレッドをブロックしますか?

どちらのアプローチがあなたにとってより良いと思われますか?またその理由は何ですか? 他のアプローチは大歓迎です。

4

1 に答える 1

2
  1. いいえ。ASP.NET と IIS は、それぞれの HTTP 要求/応答を独自のスレッドで実行します。ASP.NET での非同期プログラミングは、要求のスレッド化を処理することではなく、要求ごとにより多くの作業を行うこと (別のスレッドで無関係な SQL クエリを実行するなど) に重点を置いています。

  2. わかりません。Tasks にはあまり詳しくありません。

  3. はい、はい。

私はこのようにします(疑似コード):

  1. ファイルを処理してからバックグラウンド スレッドで (単純なSystem.Threading.Threadインスタンスを使用して) 処理します。これは、IIS 要求/応答スレッドがブロックされず、クライアントに HTML をすぐに返すことができることを意味します。
  2. このファイル処理ジョブへのトークンまたは参照をどこかに保存します。次に、「/processingJobs/job123」(job123 はジョブ ID) への 303 リダイレクトを返します。
  3. の actionHandler はGET processingJobs、ジョブ 123 のバックグラウンド スレッドを検索し、完了しているかどうかを確認します。完了していない場合は、「ジョブが処理されています。更新されたステータスについては、ページを再度更新してください」という HTML 応答を返します。 5 ~ 10 秒ごとにページを更新する小さな JavaScript。
  4. ジョブが完了したら、処理されたオーディオ ファイルをcontent-disposition:ヘッダーと共に返します。

この手法は、オーディオ処理をすべて同時に行うのではなく、個別のプロセスまたはキュー システムで処理する場合、うまくスケールアップできます。

一般的なガイドライン: HTTP 要求/応答が 100 ミリ秒以内に完了できない場合は、バックグラウンドでジョブを実行し、すぐにステータス メッセージを返します。

于 2013-03-07T03:03:23.433 に答える