我有一个C#windows窗体应用程序,它有许多进程。 这些进程在不同的线程上运行,并且所有进程都与Log Form类进行通信,并对日志窗口和进度条进行更新。我使用下面的代码,到目前为止工作正常,但是,我有几个问题。
delegate void SetTextCallback(string mxID, string text);
public void UpdateLog(string mxID, string text)
{
if (txtOutput.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(UpdateLog);
this.BeginInvoke(d, new object[] { mxID, text });
}
else
{
UpdateProgressBar(text);
}
}
请问,反复调用上面的代码大约10次,给我错误,例外或一般问题?.....或者更重要的是,它应该给我任何这些问题吗?
偶尔我会得到OutofMemory Exceptions,程序似乎总是在这段代码中崩溃......
答案 0 :(得分:2)
是的,此代码在技术上可能导致OOM。当UI线程无法跟上工作线程时,就会发生这种情况。每个Control.BeginInvoke()都将委托添加到由Windows窗体维护的内部List<Delegate>
。消息泵清空该列表。如果它无法跟上工作线程调用BeginInvoke的速率,那么列表会无限制地增长,并最终导致OOM。
如果真的每秒只调用10次,并且代码仅更新进度条和,那么UI线程处于空闲状态OOM永远不会发生。确实发生这种情况表明你以某种方式将此方法称为 lot 的频率高于每秒10次。或者真正的代码不只是更新PB,“UpdateLog”名称表明它确实如此。使用Invoke而不是BeginInvoke可以解决这个问题,但会降低工作人员的速度。
答案 1 :(得分:1)
BeginInvoke返回一个在代码中被忽略的IAsyncResult。只需使用Invoke。
答案 2 :(得分:1)
此代码没问题,异常的原因是程序中的其他位置。您可以通过直接调用UpdateProgressBar或通过BeginInvoke来调优,而不是调用UpdateLog。
delegate void SetTextCallback(string text); public void UpdateLog(string mxID, string text) { if (txtOutput.InvokeRequired) { SetTextCallback d = new SetTextCallback(UpdateProgressBar); this.BeginInvoke(d, new object[] { text }); } else { UpdateProgressBar(text); } }
但我相信这篇文章中没有显示其他内容。