我使用C#和GsmComm库创建了简单的应用程序来发送和接收消息。如果有新的传入消息,我的应用程序将显示messageBox新消息到达。我的问题是,当我有许多新消息时,messageBox将显示如此多的messageBox通知。如何使用代码显示最后一个消息框?
这个mycode:
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();
但是当新表单打开时,同样的问题第一个表单show无法关闭。这是我的参考:https://stackoverflow.com/a/13445167/3319555
我非常感谢有人能帮助我......谢谢
答案 0 :(得分:1)
如果您正在使用第二种显示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有很多信息。这可以像在表单类中添加类似下面的方法一样简单:
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