似乎我在理解有关C#中的异步操作以及控制器中的ASP.NET MVC这一主题时遇到了大量问题。
我的网页上的所有 AJAX-Requests 都有控制器。每个我都有一个动作。现在我尝试像'通知系统'那样实现。我创建了一个处理队列中通知的类,它通过使用SessionID的字典选择。
因为我正在使用 Reverse-AJAX ,所以需要在服务器上保存处理AJAX-Response的线程。因此,我将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)
,消息:&gt;&gt;此时无法启动异步操作。异步操作只能在异步处理程序或模块中启动,或者在页面生命周期中的某些事件中启动。如果在执行页面时发生此异常,请确保将页面标记为<%@ Page Async="true" %>
。此异常还可能表示尝试调用“异步void”方法,该方法通常在ASP.NET请求处理中不受支持。相反,异步方法应该返回一个Task,调用者应该等待它。&lt;&lt;
我需要AsyncController
吗?其他方法不是异步的,因为这些只是简单的响应。
我尝试将public async void pollingAsync()
与public async string pollingCompleted(string response)
结合使用,但每次参数都是null
。
我的问题是以上以及如何解决问题。有没有更好的解决方案,什么时候可以实现?
我感谢任何帮助!
答案 0 :(得分:2)
请勿使用async void
,而是使用async Task
。 async void
操作通常会被解雇,因为您无法异步等待它们。此外,使用AsyncController
时无需使用async-await
。您可以阅读有关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
这样的技术,这甚至可以非常简单和友好。我建议调查一下。