1

我想要做的是在等待聊天消息(或 MSMQ 消息)到来时使用 asp.net 4.5 async/await 实现 100% 的线程敏捷性。async/await 可以将 HTTP 请求处理线程释放到线程池中,但是如何在等待聊天消息到来时不使用任何线程呢?

在 java 中,我可以使用最新的 Jersey REST API 使用 @ManagedAsync/@Suspended 注释来实现这一点:

// Java code, using Jersey rest API
@Path("/Chatroom")
public class ChatHandler {
    private static final HashMap<Integer, AsyncResponse> map = new HashMap<>();

    @GET
    @Path("/JoinRoom")
    @ManagedAsync
    public void joinRoom(@PathParam("UserId") String id, @Suspended final AsyncResponse ar) {
        map.put(i, ar);
    }

    @GET
    @Path("/PostChat")
    public String sendChat(@PathParam("UserId") String id, @QueryParam("message") String message) throws InterruptedException {
        map.get(i).resume(message);
        return "Message successfully sent to user " + id;
    }
}

这是上面代码的描述。John 首先使用这样的 URL作为用户 john 加入聊天室,以便接收一些聊天消息。在相应的方法 joinRoom() 中,Jersey 将与 asp.net 4.5 中的 async/await 相同,将 http 请求线程返回到线程池中。但是在这里,我将 HttpContext、Jersey 中的 AsyncResponse 对象放在 hashmap 中以供以后使用。

然后说在接下来的 50 秒内,没有人发送聊天消息,后端 Jersey 服务器在这 50 秒内不会使用任何线程。没有线程用于等待下一条聊天消息。然后在第 51 秒,Mary 转到URL向用户 john 发送一条问候消息。在 sendChat() 方法中,我从哈希映射中检索 HttpContext (AsyncResponse),并使用聊天消息恢复它。这时,Jersey 会在 http 请求线程池中找到一个可用线程来恢复 AsyncResponse 并将聊天消息“hello”发送到 John 的浏览器。Mary 的浏览器将看到“消息已成功发送给用户 john”。

那么如何使用 asp.net async/await 实现同样的 100% 线程敏捷性呢?在我的 await 方法中,我找不到正确的方法来等待聊天消息而不占用工作线程。

4

1 回答 1

0

已经有一个为此设计的 ASP.NET 系统:SignalR。它的设计async考虑到了,因此它可以最佳地利用线程。

如果您不想使用 SignalR,则可以使用许多异步协调原语中的任何一种。TPL Dataflow 可能非常适合这种场景,或者您可以使用SemaphoreSlim我的 AsyncEx 库中TaskCompletionSource的任何原语。

于 2013-05-21T20:17:11.227 回答