单身类射击事件仅一次

问题描述

我是写单例类的新手,但是我遇到了一种奇怪的行为。在我的单例课程中,我有一个仅触发一次的事件。此事件是System.Messaging.MessageQueue类的ReceiveCompleted。我的单例类具有方法GetCartAsync,该方法通过MSMQ从另一个应用程序向“ FleetClientQueue”队列请求信息,该队列是ReceiveCompleted所预订的队列。这是单例课程:

public sealed class CartRepository : ICartRepository
{
    private CartRepository()
    {
        if (!MessageQueue.Exists(string.Format(".\\Private$\\FleetClientQueue"))) ;
        {
            fleetClientQueue = MessageQueue.Create(".\\Private$\\FleetClientQueue");
            fleetClientQueue.SetPermissions("Everyone",MessageQueueAccessRights.FullControl,AccessControlEntryType.Allow);
        }
        fleetClientQueue = new MessageQueue(".\\Private$\\FleetClientQueue");
        fleetClientQueue.Formatter = new Xmlmessageformatter(new[] { typeof(Cart) });
        fleetClientQueue.ReceiveCompleted += FleetClientQueue_ReceiveCompleted;
        fleetClientQueue.BeginReceive();
    }

    static ManualResetEvent expectedEchoReceived = new ManualResetEvent(false);
    Cart _cart = new Cart();        
    static MessageQueue fleetClientQueue;


   
    private static CartRepository instance = null;

    public static CartRepository Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new CartRepository();
            }
            return instance;
        }
    }

    private void FleetClientQueue_ReceiveCompleted(object sender,ReceiveCompletedEventArgs e)
    {
        _cart = (Cart)e.Message.Body;
        expectedEchoReceived.Set();
    }

    public async Task<Cart> GetCartAsync()
    {
        MessageQueue fleetClientServiceQueue;
        fleetClientServiceQueue = new MessageQueue(".\\Private$\\FleetClientServiceQueue");
        fleetClientServiceQueue.Formatter = new Binarymessageformatter();
        fleetClientServiceQueue.Send("RequestCartinformation");
        expectedEchoReceived.Reset();
        expectedEchoReceived.WaitOne(5000);

      

        return _cart;
       
    }
}

这是我如何从viewmodel类调用单例类的方法代码

Cart = await CartRepository.Instance.GetCartAsync();

奇怪的是,第一次调用GetCartAsync方法ReceiveCompleted事件就可以触发。之后,由于某种原因,当我从应用程序中的另一个视图模型调用GetCartAsync时,不会触发ReceiveCompleted事件。我可以在计算机管理中看到进入该队列的消息,并且它们只是在队列中不断累积,因为看起来好像单例订阅事件未对其进行处理。

请让我对发生的事情有所了解。

解决方法

仅获得一次回调的原因是您仅调用了BeginReceive。 它只消耗队列中的一项。

要继续使用回叫,请再次使用BeginReceive

private void FleetClientQueue_ReceiveCompleted(object sender,ReceiveCompletedEventArgs e)
{
    _cart = (Cart)e.Message.Body;
    expectedEchoReceived.Set();
    // Restart the asynchronous receive operation.
    fleetClientQueue.BeginReceive();
}

这是文档中列出的方法:

,

在调试您的源代码一段时间后,我发现在CartRepository的构造函数的第一行中,您忘记删除行末的分号(;)。因此,即使队列上存在创建异常的系统,您的MessageQueue.Create也会尝试每次运行。

建议您尝试捕获所有异常并尝试相应地处理它们。另外,创建后没有else语句,因此以下命令无需任何理由即可重新初始化队列:

fleetClientQueue = new MessageQueue(".\\Private$\\FleetClientQueue");

我要做的是将构造函数重写为如下内容:

private const string MessageQueueName = ".\\Private$\\FleetClientQueue";
private CartRepository()
{
    try
    {
        if (!MessageQueue.Exists(MessageQueueName))
        {
            fleetClientQueue = MessageQueue.Create(MessageQueueName);
            fleetClientQueue.SetPermissions("Everyone",MessageQueueAccessRights.FullControl,AccessControlEntryType.Allow);
        }
        else
        {
            fleetClientQueue = new MessageQueue(MessageQueueName);
        }
        fleetClientQueue.Formatter = new XmlMessageFormatter(new[] { typeof(Cart) });
        fleetClientQueue.ReceiveCompleted += FleetClientQueue_ReceiveCompleted;
        fleetClientQueue.BeginReceive();
    }
    catch (Exception e)
    {
        // do something here. eg.
        // log the error in a Log file,display message to the user or whatever...
    }
}

请注意以下事实:我创建了一个常量字符串MessageQueueName,并且在调用中使用了该字符串。您的GetCartAsync()方法使用了不同的队列名称,这很可能是错误的(“。\ Private $ \ FleetClientServiceQueue”)。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...