3
\$\begingroup\$

I have a server-client environment, where the client connects and synchronizes data with the server every 5 second.

For synchronizing I use a background thread on the client which works fine, but on one specific hardware the method GetNetworkAvailable throws out of memory exceptions occasionaly. The errors occur whitout logic, so I guess somethings just not good with this hardware. Anyways I'd like to get your opinion on my background - polling function.

private void SynchronizedWorker()
{
 bool initialization = true;
 int initializationTries = 0;
 // Sync loop
 while (!_shouldStop)
 {
 // Initialize locals
 int syncInterval = _syncInterval; // Reset Sync Interval to default
 SyncStatus syncStatus = SyncStatus; // Get current Status
 bool hasNetworkConnection = true; // Has Network connection
 try
 {
 //*******************************************
 // Check Network connection
 //*******************************************
 if (!NetworkInterface.GetIsNetworkAvailable())
 {
 hasNetworkConnection = false;
 _syncResetEvent.Set();
 syncStatus = SyncStatus.Offline;
 }
 else if (syncStatus == SyncStatus.Offline) // Is in offline - State, but Network available again recognize going online
 {
 _syncResetEvent.Set();
 hasNetworkConnection = IsServiceAvailable();
 // Sync-Status stays offline
 if (!hasNetworkConnection)
 {
 // Wait 1 minute, before retry
 syncInterval = 60000;
 }
 }
 //*******************************************
 // Proceed with Syncronisation
 //*******************************************
 if (hasNetworkConnection)
 {
 syncStatus = SyncStatus.Ok;
 // Try Initialization
 if (initialization)
 {
 try
 {
 // Sync initialization here...
 // ..............................
 ////////////////////////////////////
 }
 catch (Exception ex)
 {
 log.LogError(string.Format("Initialization Try {0}", initializationTries), ex);
 syncStatus = SyncStatus.InitializationFailed;
 }
 }
 // To many Init-Tries --> Stop
 if (initializationTries > 1)
 {
 // Proceed
 _syncResetEvent.Set();
 _syncStatus = syncStatus;
 break; // Stop Synch
 }
 // Debug
 var sw = System.Diagnostics.Stopwatch.StartNew();
 // Do Up/Download
 if (!initialization)
 {
 try
 {
 // Synchronisation with service here...
 // ..............................
 ////////////////////////////////////
 // Proceed
 _syncResetEvent.Set();
 }
 catch (Exception ex)
 {
 log.LogError("Download", ex);
 syncStatus = SyncStatus.SynchFailed;
 }
 }
 }
 // Set Sync status
 _syncStatus = syncStatus;
 }
 catch (Exception ex)
 {
 log.LogError("Sync-Worker", ex);
 _syncStatus = Core.Sync.SyncStatus.SynchFailed;
 // Proceed
 _syncResetEvent.Set();
 // Reset Force
 _syncForce = false;
 }
 finally
 {
 // Set Completed
 if (OnSyncCompleted != null)
 {
 OnSyncCompleted(downloaded, uploaded, executed);
 }
 // Always Wait for Interval
 DateTime sleepuntil = DateTime.Now.AddMilliseconds(syncInterval);
 while (sleepuntil > DateTime.Now && !_shouldStop && !_syncForce)
 {
 // Sleep
 Thread.Sleep(100);
 }
 }
 }
 // Stop
 _syncStatus = SyncStatus.Unknown;
 }
asked Oct 3, 2013 at 19:17
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$
  1. I would do the waiting for interval at the end also with an event - I find it cleaner. Something like this:

    AutoResetEvent _syncWaitEvent = new AutoResetEvent(false);
    ....
    // I assume there is a way for external callers to stop sync
    public void StopSync()
    {
     _syncForce= true;
     _syncWaitEvent.Set();
    }
    public void ForceSync()
    {
     _shouldStop = true;
     _syncWaitEvent.Set();
    }
    private void SynchronizedWorker()
    {
     ....
     // Sync loop
     while (!_shouldStop)
     {
     ....
     // wait for next interval or being woken up
     if (_syncWaitEvent.WaitOne(syncInterval))
     {
     // we have been signaled prior to the timeout expiring
     _syncForce = false;
     }
     }
    }
    
  2. I would change syncInterval to a TimeSpan (WaitOne() expects one anyway and I don't like passing values around with implicit units. Just gets you in trouble some day)

  3. It's not clear from your code what the _syncResetEvent() is used for. It's seems to be called in pretty much every case. You might want to revisit the name of it.

  4. Add a log message in the if (initializationTries > 1) block to state that you are stopping sync because init failed too many times.

svick
24.5k4 gold badges53 silver badges89 bronze badges
answered Oct 3, 2013 at 21:06
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.