private static void ConsumerMethod() { // Consumer method takes data from the blocking collection and writes it to a SQLite Database DataRecord data; SQLiteCommand cmd = conn.CreateCommand(); // Using transactions dramatically speeds up writing to SQLite SQLiteTransaction tr = conn.BeginTransaction(); cmd.Transaction = tr; while (true) { if (dataCollection.TryTake(out data)) { SQLite_Methods.InsertResultItem(cmd, data, TABLE_NAME); recordsWritten++; } else { Thread.Sleep(1); } if (recordsWritten % RECORDS_PER_TRANSACTION == 0) { tr.Commit(); tr = conn.BeginTransaction(); cmd.Transaction = tr; } if (recordsWritten == TOTAL_RECORDS) { tr.Commit(); tr.Dispose(); cmd.Dispose(); break; } } }
static void Main(string[] args) { // Start preparation for the test conn = SQLite_Methods.CreateConnection("test.db"); SQLite_Methods.CreateTableIfNotExists(conn, TABLE_NAME); // End preparation for the test // Make delegates for threads to call ThreadStart tProd = new ThreadStart(ProducerMethod); ThreadStart tCons = new ThreadStart(ConsumerMethod); Thread producerThread = new Thread(tProd); Thread producerThread2 = new Thread(tProd); Thread producerThread3 = new Thread(tProd); Thread producerThread4 = new Thread(tProd); Thread consumerThread = new Thread(tCons); // Timing C# is affected by the garbage collector. These calls negate that. GC.Collect(); GC.WaitForPendingFinalizers(); // Timing C# is affected by the processor switching between other processes on the systems. // This call negates that. TimeSpan startingTime; TimeSpan duration; startingTime = Process.GetCurrentProcess().Threads[0].UserProcessorTime; // DEMONSTRATE DIFFERENCE BETWEEN ONE AND FOUR PRODUCER THREADS BY COMMENTING OR UNCOMMENTING THE // producerThread2.Start(), producerThread3.Start(), and producerThread4.Start() LINES. producerThread.Start(); producerThread2.Start(); producerThread3.Start(); producerThread4.Start(); // ONLY ONE CONSUMER THREAD AT A TIME consumerThread.Start(); while (true) { if (producerThread.ThreadState == System.Threading.ThreadState.Stopped && consumerThread.ThreadState == System.Threading.ThreadState.Stopped) { duration = Process.GetCurrentProcess().Threads[0].UserProcessorTime.Subtract(startingTime); Console.WriteLine($"Time taken for writing {TOTAL_RECORDS} to SQLite = {duration.TotalMinutes} minutes"); break; } } }