现在要在窗体上显示日志,而在每秒要显示的日志数量很多的时候,窗体的刷新会占用很多的cpu.导致程序死在那里。
现在我想让日志延时输出。比方说原来一次要刷1000条日志,这样窗体承受的压力太大了。现在我要控制一次只刷出50条,然后分批刷出。这样程序就不会死了。
伪代码:
让线程Thread1往Queue<T>里写日志,然后有另外一个线程Thread2读取Queue<T>,Thread2就是控制一次读取50条,然后Thread.Sleep(m),再循环读取Queue,但是为什么Thread1和Thead2会冲突呢? 导致Thread2总是出现线程异常。
搞不懂。

解决方案 »

  1.   

    当然了冲突了,两个线程共同访问同一个资源,在线程中访问Queue<T>时,加把锁吧,lock(Queue<T>的实例)
    {
     写操作或读操作;
    }
      

  2.   

    用锁 解决 问题LOCK 锁住公用资源
      

  3.   

    怕麻烦就整个数据库。sqlite之类的。
      

  4.   

    你说的有道理。
    我加了锁,读了时候,写的时候都lock了,但是thread2还是会死掉。
      

  5.   

    Thread2不能直接操作界面控件的,
    要调用控件的invoke
    如:
    if(control.InvokeRequired)
    {
     control.invoke(....);
    }
    else
    {
     control.append(...);
    }
     
      

  6.   

    thread2不是直接调用页面控件。跟窗体没有关系。
      

  7.   

    public static class b{
    private static Queue<KeyValuePair<string, object[]>> _messageQueue = new Queue<KeyValuePair<string, object[]>>(50000);
    private static Thread _thread = null;
    private static void StartThread()
    {
    if (_thread == null)
    _thread = new Thread(new ThreadStart(ThreadRun));
    if (_thread.ThreadState == System.Threading.ThreadState.Unstarted)
    {
    _thread.Start();
    }
    }
    private static void ThreadRun()
    {
    KeyValuePair<string, object[]> messagePairs = new KeyValuePair<string, object[]>();
    int count = 0;
    try
    {
    lock (_messageQueue)
    {
    while (_messageQueue.Count > 0)
    {
    lock (_messageQueue)
    {
    messagePairs = _messageQueue.Dequeue();
    }
    int id = (int)(messagePairs.Value[0]);
    string formId = messagePairs.Value[1] as string;
    string message = messagePairs.Value[2] as string;
    ........//写日志
    if (count++ >= 20)//todo
    {
    count = 0;
    Thread.Sleep(20000);
    }
    }
    }
    Thread.Sleep(1000);
    }
    catch
    {
    }
    }
    public static void WriteInfo(string message, string formId)
    {
    StartThread();
    KeyValuePair<string, object[]> pair = new KeyValuePair<string, object[]>(INFOR_KEY, new object[] { 0, formId, message });
    lock (_messageQueue)
    {
    _messageQueue.Enqueue(pair);
    }
    }
    }
    thread1:代码里有异常信息的时候 ,会调用Class b的WriteInfo(string message, string formId)方法。
    往_messageQueue里扔信息进取,thread2就一直在读取_messageQueue,然后输出日志。
      

  8.   

    BackgroundWorker
    lock 关键字以及 AutoResetEvent 和 ManualResetEvent 类对主线程和两个辅助线程进行线程同步