解决此问题的常用方法是将发送警报的代码与显示警报的代码解耦。
首先,您应该创建一个类,该类的唯一目的是将更新传递给正在侦听的任何UI。
public class MessageUpdater
{
public event EventHandler<string> MessageSent;
public void SendMessage(string message)
{
this.MessageSent?.Invoke(this, message);
}
}
AlertBox
你只要接受一个
MessageUpdater
实例并更新
Label
每当
MessageSent
事件被激发。
public partial class AlertBox : Form
{
public AlertBox()
{
InitializeComponent();
}
private MessageUpdater _messageUpdater = null;
public MessageUpdater MessageUpdater
{
set
{
if (_messageUpdater != null)
{
_messageUpdater.MessageSent -= UpdateMessage;
}
if (value != null)
{
_messageUpdater = value;
_messageUpdater.MessageSent += UpdateMessage;
}
}
}
private void UpdateMessage(object sender, string message)
{
if (this.InvokeRequired)
{
this.Invoke((Action)(() => this.UpdateMessage(sender, message)));
}
else
{
this.MessageLabel.Text = message;
}
}
}
消息更新程序
(并删除现有的一个),然后在需要时将调用编组到UI线程。
var mu = new MessageUpdater();
var counter = 0;
var timer = new System.Threading.Timer((System.Threading.TimerCallback)(x =>
{
mu.SendMessage((counter++).ToString());
}), null, TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0));
var ab = new AlertBox();
ab.MessageUpdater = mu;
ab.ShowDialog();
这里棘手的部分是
System.Threading.Timer
我过去常常把信息推送到
消息更新程序
所以
.ShowDialog
不会冻僵的。