Пока оба потока не помечены как фоновые потоки, приложение будет работать до тех пор, пока оба потока не завершатся. Так что на самом деле все, что вам нужно сделать, это заставить каждый поток отдельно выходить чисто. В случае потока, выполняющего запись в базу данных, это может означать исчерпание очереди производителя / потребителя и проверку флага для выхода.
Я показал подходящую очередь производителя / потребителя здесь - работник просто будет:
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<>
- обратите внимание, что процесс не завершится, пока читатель и writer не завершат работу корректно. Если вы не хотите опустошать очередь (т.е. вы хотите быстрее выйти из системы и забыть о незавершенной работе), тогда хорошо - добавьте куда-нибудь дополнительный (изменчивый) флаг.
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");
}
}