我做了一个实时往数据库写入的程序,2秒一写入
我在窗体上放了好多控件,比如写入前的时间,写入后的时间,这次写入需要多少时间,还有写入的内容(假设每次内容随机变化)
因为一下子需要写入 几十条记录,所以写入的时候 如果用 windows.forms.timer 控件,会造成暂时性的主界面 假死所以我用线程 System.Timers.Timer 写入。在 timer 的 Elapsed 事件里 if (this.InvokeRequired)
{
dTmr dtr = new dTmr(ThreadWdb);
this.Invoke(dtr);
}
else
{
ThreadWdb();
} dtmr 是委托, ThreadWdb(); 函数就是写入数据库的函数,在里面有很多窗体控件。也许是我流程不对吧,我发现这么弄,每次写入的时候 窗体还是假死。这个该怎么解决啊,如果还假死的话,那我费这么大劲还不如用原来的 windows.forms.timer 控件简单呢。
我在窗体上放了好多控件,比如写入前的时间,写入后的时间,这次写入需要多少时间,还有写入的内容(假设每次内容随机变化)
因为一下子需要写入 几十条记录,所以写入的时候 如果用 windows.forms.timer 控件,会造成暂时性的主界面 假死所以我用线程 System.Timers.Timer 写入。在 timer 的 Elapsed 事件里 if (this.InvokeRequired)
{
dTmr dtr = new dTmr(ThreadWdb);
this.Invoke(dtr);
}
else
{
ThreadWdb();
} dtmr 是委托, ThreadWdb(); 函数就是写入数据库的函数,在里面有很多窗体控件。也许是我流程不对吧,我发现这么弄,每次写入的时候 窗体还是假死。这个该怎么解决啊,如果还假死的话,那我费这么大劲还不如用原来的 windows.forms.timer 控件简单呢。
你调试下,,是不是每次都在执行这个
else
{
ThreadWdb();
} 你应该另起一个线程。。在这个线程委托函数中进行数据库的写入。。
这里线程的同步控制有点麻烦。。如果要简单点的话,我有个想法。
这个是线程过程函数
void ThreadPro()
{
while(true)
{
if(有要写的数据)
{
//数据库操作
} }
//这样时刻监控
如果非要2秒写一次,,就定义一个信号量。。每隔两秒进入while(true)里面
也可以定义一个全局变量,通过主线中Timer程控制
while(true)中对该变量进行判断,什么时候休眠。(这时要同步来保证线程安全) 下面的方法是最安全,最好的办法,也是最复杂的同步控制
}给段代码你参考/*下面的示例演示使用 lock 关键字以及 AutoResetEvent 和 ManualResetEvent 类对主线程和两个辅助线程进行线程同步。有关更多信息,请参见 lock 语句(C# 参考)。 该示例创建两个辅助线程。一个线程生成元素并将它们存储在非线程安全的泛型队列中。有关更多信息,请参见 Queue。另一个线程使用此队列中的项。另外,主线程定期显示队列的内容,因此该队列被三个线程访问。lock 关键字用于同步对队列的访问,以确保队列的状态没有被破坏。 除了用 lock 关键字来阻止同时访问外,还用两个事件对象提供进一步的同步。一个事件对象用来通知辅助线程终止,另一个事件对象由制造者线程用来在有新项添加到队列中时通知使用者线程。这两个事件对象封装在一个名为 SyncEvents 的类中。这使事件可以轻松传递到表示制造者线程和使用者线程的对象。SyncEvents 类是按如下方式定义的: */using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic; public class SyncEvents
{
public SyncEvents()
{ _newItemEvent = new AutoResetEvent(false);
_exitThreadEvent = new ManualResetEvent(false);
_eventArray = new WaitHandle[2];
_eventArray[0] = _newItemEvent;
_eventArray[1] = _exitThreadEvent;
} public EventWaitHandle ExitThreadEvent
{
get { return _exitThreadEvent; }
}
public EventWaitHandle NewItemEvent
{
get { return _newItemEvent; }
}
public WaitHandle[] EventArray
{
get { return _eventArray; }
} private EventWaitHandle _newItemEvent;
private EventWaitHandle _exitThreadEvent;
private WaitHandle[] _eventArray;
}
public class Producer
{
public Producer(Queue <int> q, SyncEvents e)
{
_queue = q;
_syncEvents = e;
}
// Producer.ThreadRun
public void ThreadRun()
{
int count = 0;
Random r = new Random();
while (!_syncEvents.ExitThreadEvent.WaitOne(0, false))
{
lock (((ICollection)_queue).SyncRoot)
{
while (_queue.Count < 20)
{
_queue.Enqueue(r.Next(0,100));
_syncEvents.NewItemEvent.Set();
count++;
}
}
}
Console.WriteLine("Producer thread: produced {0} items", count);
}
private Queue <int> _queue;
private SyncEvents _syncEvents;
} public class Consumer
{
public Consumer(Queue <int> q, SyncEvents e)
{
_queue = q;
_syncEvents = e;
}
// Consumer.ThreadRun
public void ThreadRun()
{
int count = 0;
while (WaitHandle.WaitAny(_syncEvents.EventArray) != 1)
{
lock (((ICollection)_queue).SyncRoot)
{
int item = _queue.Dequeue();
}
count++;
}
Console.WriteLine("Consumer Thread: consumed {0} items", count);
}
private Queue <int> _queue;
private SyncEvents _syncEvents;
} public class ThreadSyncSample
{
private static void ShowQueueContents(Queue <int> q)
{
lock (((ICollection)q).SyncRoot)
{
foreach (int item in q)
{
Console.Write("{0} ", item);
}
}
Console.WriteLine();
} static void Main()
{
Queue <int> queue = new Queue <int>();
SyncEvents syncEvents = new SyncEvents(); Console.WriteLine("Configuring worker threads...");
Producer producer = new Producer(queue, syncEvents);
Consumer consumer = new Consumer(queue, syncEvents);
Thread producerThread = new Thread(producer.ThreadRun);
Thread consumerThread = new Thread(consumer.ThreadRun); Console.WriteLine("Launching producer and consumer threads...");
producerThread.Start();
consumerThread.Start(); for (int i=0; i <4; i++)
{
Thread.Sleep(2500);
ShowQueueContents(queue);
} Console.WriteLine("Signaling threads to terminate...");
syncEvents.ExitThreadEvent.Set(); producerThread.Join();
consumerThread.Join();
} }
使用BackgroundWorker组件dowork事件来插入数据和监听。