收到新消息时关闭 MessageBox
Close MessageBox when incoming new message
我创建了使用 C# 和 GsmComm 库发送和接收消息的简单应用程序。如果有新的传入消息,我的应用程序将显示新消息到达的消息框。我的问题是当我有很多新消息时,messageBox 会显示很多 messageBox 通知。如何使用代码只显示最后一个消息框?
这个我的代码:
private void comm_MessageReceived(object sender, MessageReceivedEventArgs e)
{
var obj = e.IndicationObject;
if (obj is MemoryLocation)
{
var loc = (MemoryLocation)obj;
var msg = string.Format("New message received in storage \"{0}\", index {1}.",
loc.Storage, loc.Index);
MessageBox.Show(msg);
return;
}
}
我很难解决这个问题,我尝试了另一种使用表单显示新传入通知的方法 form1.showDialog();
但同样的问题是,当新表单打开时,第一个表单显示无法关闭。这是我的参考:
如果有人能帮助我,我真的很感谢..谢谢
如果您正在使用第二种显示带有 form.ShowDialog()
的表单的解决方案,您可以将表单存储在列表中。然后,当需要显示新表单时,您可以遍历列表并使用 form.Close()
关闭每个打开的表单。假设您的 comm_MessageReceieved 方法是另一个线程上的 运行,我假设它是通过 IO 完成端口驱动的,那么可能是这样的?
List<MyForm> formList = new List<MyForm>();
readonly object formListLock = new object();
private void comm_MessageReceived(object sender, MessageReceivedEventArgs e)
{
/// you need to lock the List for thread safe access
lock (formListLock)
{
/// iterate over a copy of the list to avoid mutating the list under iteration
foreach (MyForm form in formList.ToList())
{
form.ThreadSafeClose();
}
}
string msg = "message";
using (MyForm form = new MyForm(msg))
{
lock (formListLock) { formList.Add(form); }
form.ShowDialog();
lock (formListLock) { formList.Remove(form); }
}
}
这只是我的想法,但可能是您可以采取的另一个可能的方向。
您必须对 form.Close() 进行线程安全调用,以便它在表单的 UI 线程上处于 运行。阅读有关调用 here 的信息。关于这个主题,有很多关于 SO 的信息。这可能就像在您的表单 class:
中添加类似以下方法一样简单
public void ThreadSafeClose()
{
if (this.InvokeRequired)
{
this.Invoke(new Action(Close)); /// or BeginInvoke...
}
else
{
Close();
}
}
在此处阅读有关列表的更多信息:https://msdn.microsoft.com/en-us/library/6sh2ey19%28v=vs.110%29.aspx
在此处阅读有关锁定语句的更多信息:https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
在此处阅读有关线程同步的更多信息:https://msdn.microsoft.com/en-us/library/ms173179.aspx
还有许多可能适合您需要的线程安全集合,例如ConcurrentBag.
我创建了使用 C# 和 GsmComm 库发送和接收消息的简单应用程序。如果有新的传入消息,我的应用程序将显示新消息到达的消息框。我的问题是当我有很多新消息时,messageBox 会显示很多 messageBox 通知。如何使用代码只显示最后一个消息框?
这个我的代码:
private void comm_MessageReceived(object sender, MessageReceivedEventArgs e)
{
var obj = e.IndicationObject;
if (obj is MemoryLocation)
{
var loc = (MemoryLocation)obj;
var msg = string.Format("New message received in storage \"{0}\", index {1}.",
loc.Storage, loc.Index);
MessageBox.Show(msg);
return;
}
}
我很难解决这个问题,我尝试了另一种使用表单显示新传入通知的方法 form1.showDialog();
但同样的问题是,当新表单打开时,第一个表单显示无法关闭。这是我的参考:
如果有人能帮助我,我真的很感谢..谢谢
如果您正在使用第二种显示带有 form.ShowDialog()
的表单的解决方案,您可以将表单存储在列表中。然后,当需要显示新表单时,您可以遍历列表并使用 form.Close()
关闭每个打开的表单。假设您的 comm_MessageReceieved 方法是另一个线程上的 运行,我假设它是通过 IO 完成端口驱动的,那么可能是这样的?
List<MyForm> formList = new List<MyForm>();
readonly object formListLock = new object();
private void comm_MessageReceived(object sender, MessageReceivedEventArgs e)
{
/// you need to lock the List for thread safe access
lock (formListLock)
{
/// iterate over a copy of the list to avoid mutating the list under iteration
foreach (MyForm form in formList.ToList())
{
form.ThreadSafeClose();
}
}
string msg = "message";
using (MyForm form = new MyForm(msg))
{
lock (formListLock) { formList.Add(form); }
form.ShowDialog();
lock (formListLock) { formList.Remove(form); }
}
}
这只是我的想法,但可能是您可以采取的另一个可能的方向。
您必须对 form.Close() 进行线程安全调用,以便它在表单的 UI 线程上处于 运行。阅读有关调用 here 的信息。关于这个主题,有很多关于 SO 的信息。这可能就像在您的表单 class:
中添加类似以下方法一样简单public void ThreadSafeClose()
{
if (this.InvokeRequired)
{
this.Invoke(new Action(Close)); /// or BeginInvoke...
}
else
{
Close();
}
}
在此处阅读有关列表的更多信息:https://msdn.microsoft.com/en-us/library/6sh2ey19%28v=vs.110%29.aspx
在此处阅读有关锁定语句的更多信息:https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
在此处阅读有关线程同步的更多信息:https://msdn.microsoft.com/en-us/library/ms173179.aspx
还有许多可能适合您需要的线程安全集合,例如ConcurrentBag.