【问题标题】:MVC AsyncController BlockingMVC AsyncController 阻塞
【发布时间】:2014-09-03 10:26:48
【问题描述】:

所以我一直在关注 Steven Sanderson 在 SignalR 和 ASP.NET Async 上的 TechDays Talk。我在执行以下操作时遇到了问题

public class SomeController : AsyncController
{
    static TaskCompletionSource<String> _nextMessage
        = new TaskCompletionSource<string>();

    [HttpPost]
    public ActionResult PostMessage(string message)
    {            
        _nextMessage = new TaskCompletionSource<string>();
        oldNextMessage.SetResult(message);
        return Content("success");
    }

    public async void GetMessages()
    {
        Response.ContentType = "text/event-stream";
        while (true)
        {
            var message = await _nextMessage.Task;
            Response.Write("data: " + message + "\n\n");
            Response.Flush();
        }

    }
}

GetMessages 在第一次调用时似乎被阻塞,但一旦超时,它就会开始按预期工作。

所以我加载了发布和运行 GetMessages 的 javascript。在第一次调用 GetMessages 时,它挂起(如预期)在

await _nextMessage.Task;

但它不会让我从任何地方(包括浏览器的其他实例)调用 PostMessage 这是在我的开发机器上,所以它可能是一个线程问题,但我认为这样做的全部目的是允许线程处理多个事情。除了第一次超时后,它开始按预期工作,我可以在其中发布并立即获得响应。但是如果我刷新页面,我会遇到同样的问题。有想法该怎么解决这个吗?顺便说一句,我正在使用 Eventsource,但是当我进行长轮询时会出现同样的问题,例如

    public async Task<string> GetNextMessage()
    {

        return await _nextMessage.Task;
    }

使用调用 GetNextMessage() 的 javascript 循环函数

【问题讨论】:

  • 尝试禁用会话状态。
  • 我如何在 MVC4 中做到这一点。 Google 让我失望了。
  • [SessionState(SessionStateBehavior.Disabled)]
  • 看来我需要 sessionstate 才能让我的任务正常工作
  • 我认为禁用会话状态使我的控制器无法同时调用 GetMessage 并继续使用 PostMessage。我结束了下面的帖子

标签: asp.net-mvc async-await


【解决方案1】:

这就是我最终使用的东西

[SessionState(SessionStateBehavior.Disabled)]
public class SomeController : AsyncController
{
    static TaskCompletionSource<String> _nextMessage = 
        new TaskCompletionSource<string>();

    public void PostMessage(string message)
    {
        var CreationJObj = FormUtils.AsciiToJObject(Request.Form[0]);
        var CreationObj = FormUtils.FromJObject<MessageDisplayVO>(CreationJObj);
        Parallel.Invoke(() => { _nextMessage.SetResult(CreationObj.Message); });
        _nextMessage = new TaskCompletionSource<string>();

    }

    public async void GetMessages()
    {
        Response.ContentType = "text/event-stream";
        var oldMessage = _nextMessage;
        var message = await oldMessage.Task;
        Response.Write("data: " + message + "\n\n");
        Response.Flush();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-29
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 2012-02-20
    • 1970-01-01
    相关资源
    最近更新 更多