As stated in edit to original question, I discovered I didn't need the delegate after all:
public class MessageController : AsyncController
{
public void IndexAsync()
{
AsyncManager.OutstandingOperations.Increment(1);
Task<Message>.Factory.StartNew(() =>
{
var queue = new MessageQueue(@".\private$\path-to-queue");
while (true)
{
var result = queue.BeginReceive();
queue.Formatter = new XmlMessageFormatter(new[] {typeof (string)});
var message = queue.EndReceive(result);
return message;
}
}).ContinueWith(t =>
{
AsyncManager.Parameters["message"] = t.Result.Body.ToString();
AsyncManager.OutstandingOperations.Decrement();
}
);
}
public JsonResult IndexCompleted(string message)
{
return Json(message, JsonRequestBehavior.AllowGet);
}
}
One thing I will note, though... I didn't consider that there would be multiple instances of the controller polling the queue for messages, so you end up with a situation where the browser sessions are competing for messages. One browser will get the first message, other browser will get the second, etc. I ended up switching this implementation over to SignalR-- just waiting for the .NET client to move into release phase.