簡體   English   中英

MVC4 WebApi進程啟動器

[英]MVC4 WebApi process launcher

我有一個MVC4 API REST嘗試在新線程中啟動進程。 我正在使用框架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休息調用(/ task / slowtask / launch),並期望202(接受)非常快。

使用Fiddler Web調試器我發出請求,代碼進入Launch(// 1),然后進入await(// 3),創建並啟動慢速任務並返回Accepted(// 2)。 但在這一點上,Fiddler沒有顯示202結果。 見附圖:

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

當慢速任務結束時,代碼繼續捕獲exitcode(// 4),然后202被捕獲到Fiddler中。

這很奇怪,因為很久以前我做過回歸。 我錯過了什么? 如何更改該代碼以便非常快速地返回202並忘記該任務。

注意 :我知道如何使用非框架4.5功能,我正在嘗試學習如何使用async / await。

我認為這是因為runProcessAsync()在請求的同步上下文上運行。 如果您不想這樣,可以使用Task.Run(() => runProcessAsync(id)); 但請注意這一點,因為IIS可以在此期間回收您的AppDomain,因此runProcessAsync()可能無法完成。

最簡單的方法是只更改runProcessAsync以返回Task 請記住, async方法應盡可能返回Task / Task<T> ,並且只在必要時才返回void

但是,我必須提醒你,這是非常危險的。 ASP.NET是一個HTTP服務器,因此如果沒有活動請求,它可以隨意刪除您的AppDomain。 這意味着你“用exitcode做更多的東西”只會從地球上掉下來。

我有一個帶有BackgroundTaskManager博客文章 ,您可以使用它來向ASP.NET運行時注冊Task 如果已注冊的Task尚未完成,它將嘗試延遲AppDomain關閉。 然而,這只是“盡力而為”; 這種事情無法保證。 在ASP.NET中運行的任何與活動請求無關的代碼都是危險的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM