3
我想实现网聊。异步操作完成,但结果不发送给浏览器
后端是一个双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);
}
}
但实际上没有发送。
检查提琴手,我看到请求,但我从来没有得到答复。
[SessionState(SessionStateBehavior.ReadOnly)]
public class ChatController : AsyncController
我还必须将SessionStateBehaviour设置为Readonly,否则异步操作会阻塞整个页面。
编辑: 这里是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);
}
}
}
它了相同的思路中refered博客文章
EDIT2: 顺便说一句,未收到任何时候,因此等待超时发挥作用,应对回报。所以它似乎崩溃了某处。任何想法如何记录这个?
您设置了一个断点并确认它正在调用'this.AsyncManager.OutstandingOperations.Decrement();'的代码? –
在'CheckForMessagesAsync'中发布相关代码,并在回调中添加日志记录。 –
与您的问题并不真正相关,但在'IndexAsync'的catch子句中,您应该递减异步操作计数器。如果你实际上没有排队回调,那么它将永远不会被调用。或者,您可以选择仅在从“CheckForMessagesAsync”成功返回后才增加它。 –