Gracefully closing multithreading application? Gracefully closing multithreading application? database database

Gracefully closing multithreading application?


As long as both threads are not marked as background threads, the app will keep running until both threads exit. So really, all you need to do is to get each thread separately to exit cleanly. In the case of the thread that writes to the database, this may mean exhausting a producer/consumer queue and checking a flag to exit.

I showed a suitable producer/consumer queue here - the worker would just be:

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...}

Here's a full example based on SizeQueue<> - note that the process doesn't exit until the reader and writer have exited cleanly. If you don't want to have to drain the queue (i.e. you want to exit sooner, and forget any pending work), then fine - add an extra (volatile) flag somewhere.

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


Assuming "call abort method" means aborting the thread using Thread.Abort. Don't do that.

You are effectively crashing your app. There are plenty cleaner ways of doing this with Monitors.

Nonetheless, you should not be getting inconsistent data in your DB when your app crashes that's why you have DB transactions which have the ACID properties.

VERY IMPORTANT EDITYou said: you do not use transactions for performance reasons, and instead use mutexes. This is WRONG on quite a few levels. Firstly, transactions can make certain operations faster, for example try inserting 10 rows into a table, try it again within a transaction, the transaction version will be faster. Secondly, what happens when/if your app crashes, do you corrupt your DB? What happens when multiple instances of your app are running? Or while you run reports against your DB in query analyzer?


Your mutex wait should involve a timeout. Each thread's outer loop can check for a 'please close now' flag. To shut down, set the 'please close now' flag for each thread, then use 'join' to wait for each thread to finish.