2015-09-08 85 views
1

看來,我有大量的問題來理解有關C#中的異步操作以及特別是Controller中的ASP.NET MVC的主題。實現異步控制器動作時的問題和錯誤

我有一個控制器我所有的AJAX-請求從我的網頁。對於每一個我有一個行動。現在我嘗試像'通知系統'一樣實施。我創建了一個處理Queue中的通知的類,它使用SessionID通過字典選擇。

由於我使用的是Reverse-AJAX,因此需要在服務器上保留有關AJAX響應的線程。因此,我使用Thread.Sleep結合while來檢查隊列是否包含元素。這裏是控制器的一部分:

public class AJAXController : AsyncController 
{ 
    public async void polling() 
    { 
     if (Session["init"] == null) //so the sessionID is not changing on every request 
      Session.Add("init", 0); 
     NotificationQueue queue = 
         NotificationQueue.getInstance(HttpContext.Session.SessionID); 

     object responseObj = null; 
     responseObj = await Task.Run(() => 
     { 
      while (queue.getSize() == 0) 
       Thread.Sleep(200); 
      return queue.getNextQueueElement(); //behind this is queue.Dequeue(); 
     }); 
     Response.Write(new JavaScriptSerializer().Serialize(responseObj)); 
    } 
} 

基本上,我不知道現在是什麼與不正確的代碼 - 既不是我知道有是正確的。

語法正確,但是當我嘗試使用網站時,服務器回答如下:500 (internal Server error),消息:>>異步操作此時無法啓動。異步操作只能在異步處理程序或模塊內啓動,或者在頁生命週期中的某些事件期間啓動。如果執行頁面時發生此異常,請確保頁面標記爲<%@ Page Async="true" %>。此異常也可能表示嘗試調用「異步無效」方法,該方法在ASP.NET請求處理中通常不受支持。相反,異步方法應該返回一個Task,並且調用者應該等待它。 < <

我需要AsyncController嗎?其他方法不是異步的,因爲這些只是簡單的響應。

我試過與public async string pollingCompleted(string response)結合使用public async void pollingAsync(),但每次參數都是null

我的問題是上述以及我如何解決問題。有沒有更好的解決方案,如果是的話,我該如何實現?

我感謝任何幫助!

+1

與您的問題並不真正相關,但這似乎是使用SignalR代替Ajax的好用例。 –

回答

2

請勿使用async void,請改爲使用async Task。因爲你無法異步地等待他們,所以操作通常會失火併且遺忘。另外,使用async-await時無需使用AsyncController。你可以閱讀更多有關here

您需要:

public async Task PollingAsync() 
{ 
    if (Session["init"] == null) //so the sessionID is not changing on every request 
     Session.Add("init", 0); 
    NotificationQueue queue = 
         NotificationQueue.getInstance(HttpContext.Session.SessionID); 

    while (queue.GetSize() == 0) 
     await Task.Delay(200); 

    var responseObj = queue.getNextQueueElement(); 
    Response.Write(new JavaScriptSerializer().Serialize(responseObj)); 
} 

一般來說,作爲一個側面說明,您可以通過使用的WebSockets繞過「輪詢」的經驗,擁有技術,如SignalR這是甚至變得相當容易和友好。我建議你調查一下。

+0

也許是一個'CancellationToken','Task.Delay'等 – Jodrell

+0

感謝您的回答,polling()方法現在被調用(不像以前那樣),但是我得到了同樣的錯誤。 我可以試試'SignalR',你能推薦任何教程或博客嗎?該文件似乎非常廣泛,我已經沒有時間了.. – Ba5t14n

+0

@ Ba5t14n我修改了一下我的答案,使用'Task.Delay'代替。改爲嘗試。 –