工作這麼多天之後,我有一個可行的解決方案。它可能不漂亮,但它的工作原理,也許一些想法可以爲其他人有用,所以它在這裏:
我將解釋我的特定問題的解決方案:我需要一個按鈕重定向到「等待「頁面,而較長的進程在後臺運行並在完成時引發事件。收到此事件後,我們希望將用戶(自動)重定向到最終頁面。
首先,我創建了一個類來聽該事件。我試圖直接在控制器中執行此操作,但是您需要小心簽名和取消簽名,因爲顯然每個請求都會創建並銷燬控制器。在這個「監聽器類」中,當接收到事件時,我有一個布爾屬性設置爲「true」。
當第一個動作被觸發,控制器通常重定向到「等待」頁面,在這裏我有這個簡單的Java腳本重定向到新的動作:
<script type="text/javascript">
window.location = "@Url.Action("WaitThenRedirect", "AuxiliaryControllerName")";
</script>
這臺運動的漫長過程(通過另一個事件)。關鍵是我使用異步操作來完成此操作(此控制器從AsyncController繼承)。 (請注意我用了一個輔助控制器這是保持所有異步的東西分開。)這就是這個樣子(more info here):
public static event EventHandler<AuxiliaryEventsArgs> ProcessReady;
public void WaitThenRedirectAsync()
{
AsyncManager.OutstandingOperations.Increment();
ProcessReady += (sender, e) =>
{
AsyncManager.Parameters["success"] = e.success;
AsyncManager.OutstandingOperations.Decrement();
};
WaitForEvent();
}
public ActionResult WaitThenRedirectCompleted(bool success)
{
if (success)
{
return RedirectToAction("RedirectToView", "ControllerName");
}
else
{
return RedirectToAction("UnexpectedError", "ControllerName");
}
}
private void WaitForEvent()
{
bool isWaitSuccessful = true;
int waitingLoops = 0;
int waitingThreshold = 200;
int sleepPeriod = 100; // (milliseconds)
while (!EventsListener.IsTheThingReady())
{
System.Threading.Thread.Sleep(sleepPeriod);
++waitingLoops;
if (waitingLoops > waitingThreshold)
{
System.Diagnostics.Debug.WriteLine("Waiting timed out!");
isWaitSuccessful = false;
break;
}
}
isWaitSuccessful = true;
if (null != ProcessReady)
{
AuxiliaryEventsArgs arguments = new AuxiliaryEventsArgs();
arguments.success = isWaitSuccessful;
try
{
ProcessReady(null, arguments);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Error in event ProcessReady" + ex);
}
}
}
我相信這是可能使用AJAX語法的替代解決方案,但是這是我有什麼,它很好地工作。我相信這不是一個非常普遍的需求,但希望有人會受益!
您需要爲此實現同步。 –
謝謝,我會試着看看! – Pablo