优雅地关闭多线程应用程序?
-
20-08-2019 - |
题
我有一个具有两个线程的应用程序。
这使用插座和更新数据表捕获数据的第一个(主线程)
第二插件的数据表到数据库中。
中的应用工作得很好,但它关闭时,主线程完成读取数据,并调用在所述第二线程,其可以被插入到数据库Abort方法,这导致不一致的数据。
目前我使用下述溶液来克服“插入期间中止”
编辑: 强大的应答后我改变了代码
void MainThread()
{
while(Read())
{
//Read Data through socket
try
{
//Wait on Mutex1
//Update Tables
}
finally
{
//Release Mutex1
}
}
_isrunning = false;
_secondThread.Join();
}
void SecondThread()
{
while(_isrunning)
{
try
{
//Wait on Mutex1
//Insert Tables into Database using transactions
}
finally
{
//Release Mutex1
}
}
}
其他提示
只要两个线程都没有被标记为后台线程,应用程序将保持运行,直到两个线程退出。所以真的,所有你需要做的是让单独每个线程完全退出。在写入到数据库中的线程的情况下,这可能意味着排出生产者/消费者队列并检查标志以退出。
我这里呈合适的生产者/消费者队列 - 工人将只是:
void WriterLoop() {
SomeWorkItem item; // could be a `DataTable` or similar
while(queue.TryDequeue(out item)) {
// process item
}
// queue is empty and has been closed; all done, so exit...
}
下面是一个基于SizeQueue<>
一个完整的例子 - 注意,进程不会退出,直到读者和作家都干净退出。如果你不希望有地漏的队列(即要提前退出,而忘记任何未决的工作),再细 - 某处添加一个额外的(挥发性)标志
static class Program {
static void Write(object message) {
Console.WriteLine(Thread.CurrentThread.Name + ": " + message);
}
static void Main() {
Thread.CurrentThread.Name = "Reader";
Thread writer = new Thread(WriterLoop);
writer.Name = "Writer";
var queue = new SizeQueue<int>(100);
writer.Start(queue);
// reader loop - note this can run parallel
// to the writer
for (int i = 0; i < 100; i++) {
if (i % 10 == 9) Write(i);
queue.Enqueue(i);
Thread.Sleep(5); // pretend it takes time
}
queue.Close();
Write("exiting");
}
static void WriterLoop(object state) {
var queue = (SizeQueue<int>)state;
int i;
while (queue.TryDequeue(out i)) {
if(i%10==9) Write(i);
Thread.Sleep(10); // pretend it takes time
}
Write("exiting");
}
}
您互斥等待应该包括超时。每个线程的外环可以检查一个“请立即关闭”标志。要关闭,设置“请立即关闭”标志为每个线程,然后使用“加入”等待每个线程完成。
不隶属于 StackOverflow