7

新しいスレッドでプロセスを起動しようとしているMVC4APIRESTがあります。私はフレームワーク4.5を使用していて、syncを使用してclausulesを待機しようとしています。

私のコードは次のようになります:

[AcceptVerbs("POST")]
public HttpResponseMessage Launch(string id)
{
    runProcessAsync(id);   // 1                                                        

    return Request.CreateResponse(HttpStatusCode.Accepted); // 2
}

protected async void runProcessAsync(string id)
{
    int exitcode = await runProcess(id);  // 3
    string exitcodesz = string.Format("exitcode: {0}", exitcode);  // 4
    // do more stuff with exitcode
}

protected Task<int> runProcess(string id)
{
    var tcs = new TaskCompletionSource<int>();

    var process = new Process
    {
        StartInfo = { FileName = @"C:\a_very_slow_task.bat" },
            EnableRaisingEvents = true
        };
        process.Exited += (sender, args) => tcs.SetResult(((Process)sender).ExitCode);            

        process.Start();

        return tcs.Task;
    }  
}

理想的には、誰かがPOST動詞を使用してapi rest呼び出し(/ task / slowtask / launch)を実行し、202(受け入れ済み)が非常に高速であることを期待します。

Fiddler Web Debuggerを使用してリクエストを行うと、コードはLaunch(// 1)に入り、待機(// 3)に進み、遅いタスクが作成されて開始され、Acceptedが返されます(// 2)。ただし、この時点では、Fiddlerは202の結果を表示していません。添付の画像を参照してください。

http://imageshack.us/photo/my-images/703/fiddler1.png/

遅いタスクが終了すると、コードは終了コード(// 4)のキャプチャを続行し、202がFiddlerにキャプチャされます。

私はずっと前に帰国したので、それは非常に奇妙です。私が欠けているものは何ですか?202を非常に高速に返し、タスクを忘れるために、そのコードを変更するにはどうすればよいですか。

:フレームワーク4.5以外の機能でこれを行う方法を知っています。非同期/待機の使用方法を学習しようとしています。

4

2 に答える 2

4

runProcessAsync()これは、リクエストの同期コンテキストで実行されるためだと思います。それが必要ない場合は、を使用できますTask.Run(() => runProcessAsync(id));。ただし、IISはその間にAppDomainをリサイクルできるため、runProcessAsync()完了しない可能性があるため、これには注意してください。

于 2013-02-18T09:07:41.873 に答える
1

runProcessAsync最も簡単な方法は、を返すように変更することTaskです。asyncメソッドは可能な限りTask/を返す必要があり、必要な場合にのみ戻る必要あることを忘れないでください。Task<T>void

ただし、これは非常に危険であることに注意する必要があります。ASP.NETはHTTPサーバーであるため、アクティブな要求がない場合は、必要に応じてAppDomainを自由に削除できます。これは、「exitcodeでさらに多くのことを行う」ことは、地球の表面から外れることを意味します。

ASP.NETランタイムにを登録するために使用できるブログ投稿がありBackgroundTaskManagerます。完了していないTask登録済みのが存在する場合、AppDomainのシャットダウンを遅らせようとします。Taskただし、これは単なる「最善の努力」です。そのようなことを保証するものではありません。アクティブな要求に関連付けられていないASP.NETで実行されているコードは、危険な状況です。

于 2013-02-15T20:31:09.383 に答える