1

在我的 dll 中,我公开了一个事件,如下所示:

 public delegate void LogMsgEventHandler(object sender, LogEventArgs e);

        public event LogMsgEventHandler newLogMessage;

        public class LogEventArgs : EventArgs
        {
            public string logMsg;
        }

        protected virtual void OnChanged(LogEventArgs e)
        {
            if (newLogMessage != null)
                newLogMessage(this, e); 
        }

各种方法触发事件以记录操作细节。在使用 dll 的主窗体上,我将任何日志消息输出到列表框:

 slotUtil.newLogMessage += new slotUtils.LogMsgEventHandler(slotUtil_newLogMessage);

..

  void slotUtil_newLogMessage(object sender, slotUtils.LogEventArgs e)
        {
            lbDebug.Items.Add(e.logMsg);
        }

问题是如果日志事件触发得太快,表单就会冻结。我认为这是一个线程问题?我怎样才能修复这个表单更新流畅的设计?这是一个糟糕的设计吗?我的备用设计 ID 也将所有日志记录存储在 dll 中的私有字符串中,然后仅在调用特定方法时转储日志。想法?

谢谢!

4

1 回答 1

2

如果您的 dll 中的类实例不在另一个线程中,则这不是线程问题。事件处理程序

void slotUtil_newLogMessage(object sender, slotUtils.LogEventArgs e)
        {
            lbDebug.Items.Add(e.logMsg);
        }

在注册它的同一个线程中执行。

因此,如果您的实例在 UI 线程中,则此事件处理程序也在 UI 线程中执行。它将新项目添加到触发新列表框重绘的列表框。如果事件触发的速度比绘制发生的速度快,那么事件处理程序将堆积在队列中等待 Invalidates 完成。如果是这种情况,你应该尝试,至少做这样的事情:

System.Windows.Forms.Timer t;
public Form1()
{
    InitializeComponent();

    t = new System.Windows.Forms.Timer();
    t.Interval = 1000;
    t.Tick += new EventHandler(t_Tick);
}

void t_Tick(object sender, EventArgs e)
{
    for(int i = 0;i<count;i++)//you must add here only those valid strings, can't use foreach
        lbDebug.Items.Add(item);
    count = 0;
}

static int count = 0;
static string[] items = new string[5];
void slotUtil_newLogMessage(object sender, slotUtils.LogEventArgs e)
{
            t.Stop();
            items[count++] = e.logMsg;
            if (count >= items.Length)
            {
                foreach (string item in items)
                    lbDebug.Items.Add(item);
                count = 0;
            }
            else
            {
                t.Start();
            }
 }

当五个日志准备好或在最后一个日志之后经过一秒钟时,将向列表框添加项目。在将它们添加到列表框之前,您可以在数组中添加任意数量的日志(只需更改其大小)。

于 2012-11-17T12:40:09.160 回答