【问题标题】:Async operation completes, but result is not send to browser异步操作完成,但结果未发送到浏览器
【发布时间】:2011-07-04 22:12:41
【问题描述】:

我想实现一个网络聊天。

后端是双 WCF 通道。双通道在控制台或winforms中工作, 它实际上可以在网络上运行。我至少可以发送和接收消息。

作为基础,我使用了this blog post 至此,异步操作完成。

当我调试结果时,我看到消息都准备好发送到浏览器了。

[AsyncTimeout(ChatServer.MaxWaitSeconds * 1020)] // timeout is a bit longer than the internal wait
public void IndexAsync()
{
  ChatSession chatSession = this.GetChatSession();
  if (chatSession != null)
  {
    this.AsyncManager.OutstandingOperations.Increment();
    try
    {
      chatSession.CheckForMessagesAsync(msgs =>
      {
        this.AsyncManager.Parameters["response"] = new ChatResponse { Messages = msgs };
        this.AsyncManager.OutstandingOperations.Decrement();
      });
    }
    catch (Exception ex)
    {
      Logger.ErrorException("Failed to check for messages.", ex);
    }
  }
}

public ActionResult IndexCompleted(ChatResponse response)
{
  try
  {
    if (response != null)
    {
      Logger.Debug("Async request completed. Number of messages: {0}", response.Messages.Count);
    }
    JsonResult retval = this.Json(response);
    Logger.Debug("Rendered response: {0}", retval.);
    return retval;
  }
  catch (Exception ex)
  {
    Logger.ErrorException("Failed rendering the response.", ex);
    return this.Json(null);
  }
}

但实际上没有发送任何内容。

检查 Fiddler,我看到了请求,但从未得到响应。

[SessionState(SessionStateBehavior.ReadOnly)]  
public class ChatController : AsyncController

我还必须将 SessionStateBehaviour 设置为只读,否则异步操作会阻塞整个页面。

编辑: 这是 CheckForMessagesAsync:

public void CheckForMessagesAsync(Action<List<ChatMessage>> onMessages)
{
  if (onMessages == null)
    throw new ArgumentNullException("onMessages");

  Task task = Task.Factory.StartNew(state =>       
  {
    List<ChatMessage> msgs = new List<ChatMessage>();
    ManualResetEventSlim wait = new ManualResetEventSlim(false);
    Action<List<ChatMessage>> callback = state as Action<List<ChatMessage>>;
    if (callback != null)
    {
      IDisposable subscriber = m_messages.Subscribe(chatMessage =>
      {
        msgs.Add(chatMessage);
        wait.Set();
      });
      bool success;
      using (subscriber)
      {
        // Wait for the max seconds for a new msg
        success = wait.Wait(TimeSpan.FromSeconds(ChatServer.MaxWaitSeconds));              
      }
      if (success) this.SafeCallOnMessages(callback, msgs);
      else this.SafeCallOnMessages(callback, null);
    }        
  }, onMessages);
}
private void SafeCallOnMessages(Action<List<ChatMessage>> onMessages, List<ChatMessage> messages)
{
  if (onMessages != null)
  {
    if (messages == null)
      messages = new List<ChatMessage>();
    try
    {
      onMessages(messages);
    }
    catch (Exception ex)
    {
      this.Logger.ErrorException("Failed to call OnMessages callback.", ex);
    }
  }
}

这与引用的博客文章中的想法相同

编辑2: 顺便说一句,当什么都没有收到时,等待超时开始起作用,响应返回。所以它似乎在某个地方崩溃了。知道如何记录吗?

【问题讨论】:

  • 您设置了一个断点并验证它正在到达您调用this.AsyncManager.OutstandingOperations.Decrement();的代码?
  • CheckForMessagesAsync发布相关代码,并在回调中添加日志。
  • 与您的问题没有真正的关系,但在IndexAsync 的catch 子句中,您应该减少异步操作计数器。如果您实际上没有将回调排队,那么它将永远不会被调用。或者,您可以选择仅在从CheckForMessagesAsync 成功返回后才递增。
  • 谢谢。我在增量/减量调用之前和之后添加了日志消息。这就是我得到的。
  • WebProject.Controllers.ChatController|增加未完成操作 WebProject.Controllers.ChatController|发送消息到 sip:xxx@xxxx.ext ChatDAL|通知响应:WebProject.DataAccessLayer.UnifiedMessagingGatewayService.ChatResponse ChatSession|收到消息。 WebProject.Controllers.ChatController|递减杰出操作 WebProject.Controllers.ChatController|异步回调完成。 WebProject.Controllers.ChatController|异步请求已完成。消息数:1

标签: c# asp.net-mvc-3 asynccontroller


【解决方案1】:

我将 jQUERY 请求(请参阅原始博客文章)从 POST 更改为 GET。这样就解决了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多