static void Demo_Multiple_SendRequest_MultiThreaded_Correct_Lock_Unlock(object sp) { uint cycle = m_cycle; CSocketPool <CSqlite> spSqlite = (CSocketPool <CSqlite>)sp; while (cycle > 0) { //Take an async handler infinitely from socket pool for sending multiple requests from current thread CSqlite sqlite = spSqlite.Lock(); StreamSQLsWithManualTransaction(sqlite); //Put back a previously locked async handler to pool for reuse spSqlite.Unlock(sqlite); --cycle; } foreach (CSqlite s in spSqlite.AsyncHandlers) { s.WaitAll(); } }
static Task <bool> DoFuture(CSocketPool <CSqlite> sp) { TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool>(); CSqlite sqlite = sp.Lock(); if (sqlite == null) { lock (m_csConsole) Console.WriteLine("All sockets are disconnected from server"); tcs.SetResult(false); return(tcs.Task); } bool ok = false; do { if (!sqlite.BeginTrans(tagTransactionIsolation.tiReadCommited, (h, res, errMsg) => { if (res != 0) { lock (m_csConsole) Console.WriteLine("BeginTrans: Error code={0}, message={1}", res, errMsg); } })) { break; } if (!sqlite.Execute("delete from EMPLOYEE;delete from COMPANY", (h, res, errMsg, affected, fail_ok, id) => { if (res != 0) { lock (m_csConsole) Console.WriteLine("Execute_Delete: affected={0}, fails={1}, res={2}, errMsg={3}", affected, (uint)(fail_ok >> 32), res, errMsg); } })) { break; } if (!sqlite.Prepare("INSERT INTO COMPANY(ID,NAME)VALUES(?,?)")) { break; } CDBVariantArray vData = new CDBVariantArray(); vData.Add(1); vData.Add("Google Inc."); vData.Add(2); vData.Add("Microsoft Inc."); //send two sets of parameterised data in one shot for processing if (!sqlite.Execute(vData, (h, res, errMsg, affected, fail_ok, id) => { if (res != 0) { lock (m_csConsole) Console.WriteLine("INSERT COMPANY: affected={0}, fails={1}, res={2}, errMsg={3}", affected, (uint)(fail_ok >> 32), res, errMsg); } })) { break; } if (!sqlite.Prepare("INSERT INTO EMPLOYEE(EMPLOYEEID,CompanyId,name,JoinDate)VALUES(?,?,?,?)")) { break; } vData.Clear(); vData.Add(1); vData.Add(1); /*google company id*/ vData.Add("Ted Cruz"); vData.Add(DateTime.Now); vData.Add(2); vData.Add(1); /*google company id*/ vData.Add("Donald Trump"); vData.Add(DateTime.Now); vData.Add(3); vData.Add(2); /*Microsoft company id*/ vData.Add("Hillary Clinton"); vData.Add(DateTime.Now); //send three sets of parameterised data in one shot for processing if (!sqlite.Execute(vData, (h, res, errMsg, affected, fail_ok, id) => { if (res != 0) { lock (m_csConsole) Console.WriteLine("INSET EMPLOYEE: affected={0}, fails={1}, res={2}, errMsg={3}", affected, (uint)(fail_ok >> 32), res, errMsg); } })) { break; } if (!sqlite.EndTrans(tagRollbackPlan.rpDefault, (h, res, errMsg) => { if (res != 0) { lock (m_csConsole) Console.WriteLine("EndTrans: Error code={0}, message={1}", res, errMsg); } tcs.SetResult(true); }, (h, canceled) => { lock (m_csConsole) Console.WriteLine("EndTrans: " + (canceled ? "Request canceled" : "Socket closed")); tcs.SetResult(false); })) { break; } ok = true; sp.Unlock(sqlite); //put handler back into pool for reuse } while (false); if (!ok) { //Socket is closed at server side and the above locked handler is automatically unlocked lock (m_csConsole) Console.WriteLine("DoFuture: Connection disconnected error code ={0}, message ={1}", sqlite.AttachedClientSocket.ErrorCode, sqlite.AttachedClientSocket.ErrorMsg); tcs.SetResult(false); } return(tcs.Task); }