C#委托调用所需问题

时间:2010-04-12 09:14:44

标签: c# delegates

方案

我有一个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,程序似乎总是在这段代码中崩溃......

3 个答案:

答案 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);
         }
     } 

但我相信这篇文章中没有显示其他内容。