Ich habe eine MVC4 API REST versucht, einen Prozess in einem neuen Thread zu starten. Ich arbeite mit Framework 4.5 und versuche, sync und clausules zu verwenden.MVC4 WebApi Prozess Launcher
Mein Code sieht so aus:
[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;
}
}
Idealerweise jemand einen api Rest Anruf durchführen wird (/ Aufgabe/slowtask/launch) mit Postverb und erwartet sehr schnell ein 202 (angenommen).
Mit Fiddler Web Debugger Ich mache die Anfrage, der Code tritt in Launch (// 1), dann geht auf die Wartezeit (// 3), die langsame Aufgabe erstellt und gestartet und ein Akzeptiert wird zurückgegeben (// 2). Aber zu diesem Zeitpunkt zeigt Fiddler das 202-Ergebnis nicht. Siehe beigefügtes Bild:
http://imageshack.us/photo/my-images/703/fiddler1.png/
Wenn die langsame Aufgabe endet, fährt der Code den Exitcode erfassen (// 4) und dann wird die 202 in Fiddler erfaßt.
Das ist sehr seltsam, weil ich die Rückkehr vor langer Zeit gemacht habe. Was ich vermisse? Wie kann ich diesen Code ändern, um eine 202 sehr schnell zurückzugeben und die Aufgabe zu vergessen?
Hinweis: Ich weiß, wie dies mit nicht Framework 4.5 Funktionen zu tun, ich versuche zu lernen, wie async/erwarten verwenden.
Ich denke, das liegt daran, dass 'runProcessAsync()' auf den Synchronisationskontext der Anfrage läuft. Wenn Sie das nicht möchten, können Sie 'Task.Run (() => runProcessAsync (id));' verwenden. Aber seien Sie vorsichtig damit, denn IIS kann Ihre Anwendungsdomäne während dieser Zeit wiederverwenden, daher besteht die Möglichkeit, dass 'runProcessAsync() 'nicht abgeschlossen wird. – svick
Ich habe das getan und funktioniert. Es ist eine Schande, dass Sie keine richtige Antwort gegeben haben, denn Sie haben mein Problem gelöst. – Jordi