public void BackgroundWork( ) { // We're running on the background thread. Loop until we're told to exit... Logr.Log(String.Format("~A BackgroundWork thread started")); // Main loop for worker thread. It will briefly hold the m_InFlight lock when // it removes entries, and also the m_InputQueue lock in GetWork( ) as it // removes entries. DoQuandlQuery( ) will grab the cache lock when it's // adding cache entries. Obviously, no lock should be held permanently! JOS 2015-04-31 while (true) { // Wait for a signal from the other thread to say there's some work. m_Event.WaitOne( ); String[] work = GetWork( ); while (work != null) { if (work[0] == "stop") { // exit req from excel thread Logr.Log(String.Format("~A BackgroundWork thread exiting")); return; } string fkey = String.Format("{0}.{1}", work[0], work[1]); Logr.Log(String.Format("~A BackgroundWork new request fkey({0})", fkey)); if (work[0] == "quandl") { bool ok = DoQuandlQuery(work[1], work[2]); lock (m_InFlight) { m_InFlight.Remove(fkey); } } else if (work[0] == "tiingo") { bool ok = DoTiingoQuery(work[1], work[2], work[3]); lock (m_InFlight) { m_InFlight.Remove(fkey); } } else if (work[0] == "websock") { WSCallback wscb = new WSCallback(work[1], work[2], this.WSCallbackClosed); lock (m_InFlight) { m_WSCallbacks.Add(fkey, wscb); } } work = GetWork( ); } // We've exhausted the queued work, so reset the event so that we wait in the // WaitOne( ) invocation above until another thread signals that there's some // more work. m_Event.Reset( ); } }
public void BackgroundWork( ) { // We're running on the background thread. Loop until we're told to exit... Logr.Log(String.Format("~A BackgroundWork thread started")); // Main loop for worker thread. It will briefly hold the m_InFlight lock when // it removes entries, and also the m_InputQueue lock in GetWork( ) as it // removes entries. DoQuandlQuery( ) will grab the cache lock when it's // adding cache entries. Obviously, no lock should be held permanently! JOS 2015-04-31 while (true) { // Wait for a signal from the other thread to say there's some work. m_Event.WaitOne( ); Dictionary <string, string> work = GetWork( ); while (work != null) { if (work["type"] == "stop") { // exit req from excel thread Logr.Log(String.Format("~A BackgroundWork thread exiting")); return; } string fkey = String.Format("{0}.{1}", work["type"], work["key"]); Logr.Log(String.Format("~A BackgroundWork new request fkey({0})", fkey)); if (work["type"] == "quandl") { // run query synchronously here on background worker thread bool ok = DoQuandlQuery(work); // query done, so remove key from inflight, which will permit // the query to be resubmitted lock (m_InFlight) { m_InFlight.Remove(fkey); } } else if (work["type"] == "tiingo") { // run query synchronously here on background worker thread bool ok = DoTiingoQuery(work); // query done, so remove key from inflight, which will permit // the query to be resubmitted lock (m_InFlight) { m_InFlight.Remove(fkey); } } else if (work["type"] == "websock") { WSCallback wscb = new WSCallback(work, this.WSCallbackClosed); // We don't want to remove the inflight key here as there will be // async callbacks to WSCallback on pool threads when updates // arrive on the SS websock. So we leave the key in place to // prevent AddRequest, which is on the Excel thread, creating // a request for a new WSCallback. lock (m_InFlight) { m_WSCallbacks.Add(fkey, wscb); } } else if (work["type"] == "twebsock") { // We don't want to remove the inflight key here as there will be // async callbacks to TWSCallback on pool threads when updates // arrive on the tiingo websock. So we leave the key in place to // prevent AddRequest, which is on the Excel thread, creating // a request for a new TWSCallback. lock (m_InFlight) { if (m_TWSCallback == null) { m_TWSCallback = new TWSCallback(work, this.TWSCallbackClosed); if (m_PendingTiingoSubs.Count > 0) { m_TWSCallback.AddSubscriptions(m_PendingTiingoSubs); m_PendingTiingoSubs.Clear(); } } } } else if (work["type"] == "s2sub") { if (work["subcache"] == "twebsock") { // New subscription to a tiingo websock. If the TWSCallback // doesn't exist yet cache it, but if it does pass it through lock (m_InFlight) { m_PendingTiingoSubs.Add(work); if (m_TWSCallback != null) { m_TWSCallback.AddSubscriptions(m_PendingTiingoSubs); m_PendingTiingoSubs.Clear(); } } } } work = GetWork( ); } // We've exhausted the queued work, so reset the event so that we wait in the // WaitOne( ) invocation above until another thread signals that there's some // more work. m_Event.Reset( ); } }