单例 class 仅触发一次事件
Singleton class firing event only once
我是新写单例 classes 但我 运行 有一种奇怪的行为。在我的单身人士 class 上,我有一个只触发一次的事件。此事件是 System.Messaging.MessageQueue class 的 ReceiveCompleted。我的单身人士 class 有一个方法 GetCartAsync,它通过 MSMQ 从另一个应用程序请求信息到“FleetClientQueue”队列,这是订阅 ReceiveCompleted 的队列。这是单例 class:
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;
}
}
这是我如何从视图模型 class 调用单例 class 方法的代码:
Cart = await CartRepository.Instance.GetCartAsync();
奇怪的是,第一次调用 GetCartAsync 方法时,ReceiveCompleted 事件会正常触发。之后由于某种原因,当我从我的应用程序中的另一个视图模型调用 GetCartAsync 时,没有触发 ReceiveCompleted 事件。我可以在计算机管理上看到消息进入该队列,并且它们一直在队列中累积,因为看起来它们没有被单例订阅事件处理。
如果我能对正在发生的事情有一些想法,拜托了。
调试您的源代码一段时间后,我发现在 CartRepository
的构造函数的第一行中,您忘记删除行尾的分号 (;)。因此,您的 MessageQueue.Create
每次都会尝试 运行,即使队列存在于创建异常的系统上也是如此。
建议您尝试捕获所有异常并尝试相应地处理它们。此外,您在创建后没有 else
语句,因此以下命令 re-initializes the queue without reason:
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")。
你只得到一次这个回调的原因是你只调用了一次BeginReceive
。
它只消耗队列中的一项。
要继续消费,请在回调中再次调用 BeginReceive
:
private void FleetClientQueue_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
_cart = (Cart)e.Message.Body;
expectedEchoReceived.Set();
// Restart the asynchronous receive operation.
fleetClientQueue.BeginReceive();
}
这是文档中列出的方法:
我是新写单例 classes 但我 运行 有一种奇怪的行为。在我的单身人士 class 上,我有一个只触发一次的事件。此事件是 System.Messaging.MessageQueue class 的 ReceiveCompleted。我的单身人士 class 有一个方法 GetCartAsync,它通过 MSMQ 从另一个应用程序请求信息到“FleetClientQueue”队列,这是订阅 ReceiveCompleted 的队列。这是单例 class:
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;
}
}
这是我如何从视图模型 class 调用单例 class 方法的代码:
Cart = await CartRepository.Instance.GetCartAsync();
奇怪的是,第一次调用 GetCartAsync 方法时,ReceiveCompleted 事件会正常触发。之后由于某种原因,当我从我的应用程序中的另一个视图模型调用 GetCartAsync 时,没有触发 ReceiveCompleted 事件。我可以在计算机管理上看到消息进入该队列,并且它们一直在队列中累积,因为看起来它们没有被单例订阅事件处理。
如果我能对正在发生的事情有一些想法,拜托了。
调试您的源代码一段时间后,我发现在 CartRepository
的构造函数的第一行中,您忘记删除行尾的分号 (;)。因此,您的 MessageQueue.Create
每次都会尝试 运行,即使队列存在于创建异常的系统上也是如此。
建议您尝试捕获所有异常并尝试相应地处理它们。此外,您在创建后没有 else
语句,因此以下命令 re-initializes the queue without reason:
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")。
你只得到一次这个回调的原因是你只调用了一次BeginReceive
。
它只消耗队列中的一项。
要继续消费,请在回调中再次调用 BeginReceive
:
private void FleetClientQueue_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
_cart = (Cart)e.Message.Body;
expectedEchoReceived.Set();
// Restart the asynchronous receive operation.
fleetClientQueue.BeginReceive();
}
这是文档中列出的方法: