我有一个具有两个线程的应用程序。

这使用插座和更新数据表捕获数据的第一个(主线程)

第二插件的数据表到数据库中。

中的应用工作得很好,但它关闭时,主线程完成读取数据,并调用在所述第二线程,其可以被插入到数据库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           
        }
     }
}
有帮助吗?

解决方案

假设“呼叫终止方法”是指使用中止的Thread.Abort的螺纹。 不要做

您有效崩溃您的应用程序。有很多与监视器这样做的更清洁的方式。

不过,你不应该在你的数据库获取数据不一致时,你的应用程序崩溃,这就是为什么你有拥有的 ACID 性质。

<强>非常重要修改 你说:你不使用的交易性能方面的原因,而是使用互斥。这是错了好几个级别即可。首先,交易可以使某些操作变得更快,例如尝试将10行插入表,在事务内再次尝试,该交易的版本会更快。其次,当/如果你的应用程序崩溃,你破坏你的数据库会发生什么?当你的应用程序的多个实例在运行时会发生什么?或者,当你在查询分析器中运行报告对您的数据库?

其他提示

只要两个线程都没有被标记为后台线程,应用程序将保持运行,直到两个线程退出。所以真的,所有你需要做的是让单独每个线程完全退出。在写入到数据库中的线程的情况下,这可能意味着排出生产者/消费者队列并检查标志以退出。

我这里呈合适的生产者/消费者队列 - 工人将只是:

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");
    }
}

您互斥等待应该包括超时。每个线程的外环可以检查一个“请立即关闭”标志。要关闭,设置“请立即关闭”标志为每个线程,然后使用“加入”等待每个线程完成。

scroll top