gpt4 book ai didi

c# - MessageQueue 和异步/等待

转载 作者:可可西里 更新时间:2023-11-01 08:32:27 24 4
gpt4 key购买 nike

我只想在异步方法中接收我的消息!它卡住了我的用户界面

    public async void ProcessMessages()
{
MessageQueue MyMessageQueue = new MessageQueue(@".\private$\MyTransactionalQueue");
MyMessageQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });

while (true)
{
MessageQueueTransaction MessageQueueTransaction = new MessageQueueTransaction();
MessageQueueTransaction.Begin();

ContainError = false;
ProcessPanel.SetWaiting();

string Body = MyMessageQueue.Receive(MessageQueueTransaction).Body.ToString();

//Do some process with body string.

MessageQueueTransaction.Commit();
}
}

我只是像调用任何常规方法一样调用该方法,并且它没有工作!当我使用 BackgroundWorkers 而不是 async/await 时,这段代码曾经有效

想法?

最佳答案

正如 Stephen 所写,异步不会在线程中运行您的代码。幸运的是,您可以使用 TaskFactory.FromAsyncMessageQueue.BeginReceive/MessageQueue.EndReceive 异步接收消息:

    private  async Task<Message> MyAsyncReceive()
{
MessageQueue queue=new MessageQueue();
...
var message=await Task.Factory.FromAsync<Message>(
queue.BeginReceive(),
queue.EndReceive);

return message;

}

您应该注意,没有使用事务的 BeginReceive 版本。来自 BeginReceive 的文档:

Do not use the asynchronous call BeginReceive with transactions. If you want to perform a transactional asynchronous operation, call BeginPeek, and put the transaction and the (synchronous) Receive method within the event handler you create for the peek operation.

这是有道理的,因为无法保证您必须等待响应多长时间或哪个线程最终会处理完成的调用。

要使用事务,您可以这样写:

    private  async Task<Message> MyAsyncReceive()
{
var queue=new MessageQueue();

var message=await Task.Factory.FromAsync<Message>(queue.BeginPeek(),queue.EndPeek);

using (var tx = new MessageQueueTransaction())
{
tx.Begin();

//Someone may have taken the last message, don't wait forever
//Use a smaller timeout if the queue is local
message=queue.Receive(TimeSpan.FromSeconds(1), tx);
//Process the results inside a transaction
tx.Commit();
}
return message;
}

更新

正如 Rob 指出的那样,原始代码使用了从 Peek 返回的 message,这可能在 PeekReceive 之间发生了变化。在这种情况下,第二条消息将丢失。

不过,如果另一个客户端读取队列中的最后一条消息,仍然有可能发生阻塞。为防止这种情况,Receive 应该有一个小超时。

关于c# - MessageQueue 和异步/等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16100773/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com