2

In Program.cs habe ich die folgende Methode, die prüft und die Synchronisierung 5 SQL db's mit dem zentralen Server. Jeder ist getrennt von dem anderen, also dachte ich mir, die Ladezeit meines Programms zu beschleunigen, indem ich sie alle gleichzeitig laufen lasse.Gibt es eine Grenze für Hintergrundarbeiter? Technical or Common Sense

Leider ist es sehr flockig, einmal zu arbeiten, dann nicht das nächste. Die lokale Datenbank ist SQLExpress 2005 und die zentrale Datenbank ist SQL Server Standard 2005.

Gibt es eine Grenze für wie viele Verbindungen beide haben können? Wie wäre es mit Hintergrundarbeitern, kann ich nur so viele auf einmal laufen lassen? Ich bin sicher, es gibt eine viel beredtere Art, dies zu tun, ich würde sie gerne hören (sehen). Diese

ist, wie ich das nennen in Main() in Program.cs ->

if(IsSqlAvailable()) SyncNow();


internal static void SyncNow() 
    { 



      #region ConnectDB Merge Sync Background Thread 

      BackgroundWorker connectBW = new BackgroundWorker 
              { 
               WorkerReportsProgress = false, 
               WorkerSupportsCancellation = true 
              }; 
      connectBW.DoWork += new DoWorkEventHandler(connectBW_DoWork); 
      if (connectBW.IsBusy != true) 
       connectBW.RunWorkerAsync(); 

      #endregion 

      #region aspnetDB Merge Sync Background Thread 

      BackgroundWorker aspBW = new BackgroundWorker 
             { 
              WorkerReportsProgress = false, 
              WorkerSupportsCancellation = true 
             }; 
      aspBW.DoWork += new DoWorkEventHandler(aspBW_DoWork); 
      if (aspBW.IsBusy != true) 
       aspBW.RunWorkerAsync(); 

      #endregion 

      #region MatrixDB Merge Sync Background Thread 

      BackgroundWorker matrixBW = new BackgroundWorker 
              { 
               WorkerReportsProgress = false, 
               WorkerSupportsCancellation = true 
              }; 
      matrixBW.DoWork += new DoWorkEventHandler(matrixBW_DoWork); 
      if (matrixBW.IsBusy != true) 
       matrixBW.RunWorkerAsync(); 

      #endregion 



      #region CMODB Merge Sync Background Thread 

      BackgroundWorker cmoBW = new BackgroundWorker 
             { 
              WorkerReportsProgress = false, 
              WorkerSupportsCancellation = true 
             }; 
      cmoBW.DoWork += new DoWorkEventHandler(cmoBW_DoWork); 
      if (cmoBW.IsBusy != true) 
       cmoBW.RunWorkerAsync(); 

      #endregion 

      #region MemberCenteredPlanDB Merge Sync Background Thread 

      BackgroundWorker mcpBW = new BackgroundWorker 
             { 
              WorkerReportsProgress = false, 
              WorkerSupportsCancellation = true 
             }; 
      mcpBW.DoWork += new DoWorkEventHandler(mcpBW_DoWork); 
      if (mcpBW.IsBusy != true) 
       mcpBW.RunWorkerAsync(); 

      #endregion 

    } 

    static void mcpBW_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = sender as BackgroundWorker; 
     try 
     { 
      MergeRepl mcpMergeRepl = new MergeRepl(SystemInformation.ComputerName + "\\SQLEXPRESS", "WWCSTAGE", "MemberCenteredPlan", "MemberCenteredPlan", "MemberCenteredPlan"); 
      mcpMergeRepl.RunDataSync(); 
      areAllInSync += 1; 
     } 
     catch (Exception) 
     { 
      if (worker != null) worker.CancelAsync(); 
     } 
    } 

    static void cmoBW_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = sender as BackgroundWorker; 
     try 
     { 
      MergeRepl cmoMergeRepl = new MergeRepl(SystemInformation.ComputerName + "\\SQLEXPRESS", "WWCSTAGE", "CMO", "CMO", "CMO"); 
      cmoMergeRepl.RunDataSync(); 
      areAllInSync += 1; 
     } 
     catch (Exception) 
     { 
      if (worker != null) worker.CancelAsync(); 
     } 
    } 

    static void connectBW_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = sender as BackgroundWorker; 
     try 
     { 
      MergeRepl connectMergeRepl = new MergeRepl(SystemInformation.ComputerName + "\\SQLEXPRESS", "WWCSTAGE", "CONNECT", "Connect", "Connect"); 
      connectMergeRepl.RunDataSync(); 
      areAllInSync += 1; 
     } 
     catch (Exception) 
     { 
      if (worker != null) worker.CancelAsync(); 
     } 
    } 

    static void matrixBW_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = sender as BackgroundWorker; 
     try 
     { 
      MergeRepl matrixMergeRepl = new MergeRepl(SystemInformation.ComputerName + "\\SQLEXPRESS", "WWCSTAGE", "MATRIX", "MATRIX", "MATRIX"); 
      matrixMergeRepl.RunDataSync(); 
      areAllInSync += 1; 
     } 
     catch (Exception) 
     { 
      if (worker != null) worker.CancelAsync(); 
     } 
    } 

    static void aspBW_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = sender as BackgroundWorker; 
     try 
     { 
      MergeRepl aspnetdbMergeRepl = new MergeRepl(SystemInformation.ComputerName + "\\SQLEXPRESS", "WWCSTAGE", "aspnetdb", "aspnetdb", "aspnetdb"); 
      aspnetdbMergeRepl.RunDataSync(); 
      areAllInSync += 1; 
     } 
     catch (Exception) 
     { 
      if (worker != null) worker.CancelAsync(); 
     } 

    } 
+0

Für den Anfang habe ich herausgefunden, dass meine While war böse und verursacht einige der Probleme. –

Antwort

1

Sie müssen genauer sein, was die "Schuppigkeit" ist, wie manifestiert. Wenn ich das richtig verstehe, versuchen Sie manuell eine Mergereplikation mit RMO-Klassen zu fahren, wenn die Agent-Unterstützung fehlt.

Eine Sache, die zu beachten ist, dass SQL Express nur einen Scheduler unterstützt, so dass das Hinzufügen mehrerer Worker (ausstehende Anfragen) keinen großen Unterschied macht, sie stapeln sich einfach in der ausführbaren Warteschlange und kämpfen um den einen CPU, um sie auszuführen.

Zweitens bin ich nicht sicher, dass die RMO-Replikationsklassen (die ich vermute, dass Sie verwenden) Synchronisierung in mehreren, parallelen Instanzen unterstützen, also habe ich wahrscheinlich keinen Sinn, mehr als nur einen BackgroundWorker pro db (ich kann hier liege ich falsch, ich bin kein RMO-Experte.

+0

Die Flockigkeit glaube ich ist, weil Sie es genagelt haben. Ich habe versucht zu "schummeln". Ich verwende RMO und synchron die Daten damit zusammenführen. Ich dachte, ich könnte sie alle laufen lassen, aber jetzt scheint es nicht so. –

2

ich eine nur verwenden.

Ich denke, dass der BackgroundWorker es mir erlaubt, eine langwierige Aufgabe auszuführen und die Benutzeroberfläche reaktionsfähig zu halten.

Wenn ich mehrere Threads möchte, verwende ich den ThreadPool.

+0

Das macht Sinn. Gibt es einen technischen Grund, warum Sie nicht mehrere verwenden können? Mach dir keine Sorgen, ich bin verkauft, dass es keine Best Practice ist Ich fragte mich nur, ob es einen anderen Grund gab. Vielen Dank! –

+0

Der BackgroundWorker bietet einen Mechanismus, um Nachrichten zwischen der Benutzeroberfläche und Ihrer Hintergrundaufgabe auf thread-sichere Weise zu übertragen. Wenn Sie diese Art von Interaktivität benötigen, dann verwenden Sie BackgroundWorkers. Wenn Sie dies nicht tun, ist es einfacher, einen Thread vom ThreadPool zu starten (geben Sie Parallelitätsprobleme ein oder nehmen Sie sie mit). –

2

Nun, mit zu beginnen und ich bin sehr traurig, dies zu sagen, aber Ihr Code tut meinen Augen weh ...

Das ganze Chaos wie diese neu geschrieben werden kann:

 internal static void SyncNow() 
     { 
      CreateWorker(new MergeRepl(SystemInformation.ComputerName + "\\SQLEXPRESS", "WWCSTAGE", "aspnetdb", "aspnetdb", "aspnetdb")); 
      //etc... 
     } 

     private static void CreateWorker(MergeRepl repl) 
     { 
      BackgroundWorker connect = new BackgroundWorker { WorkerReportsProgress = false, WorkerSupportsCancellation = true }; 
      connect.DoWork += new DoWorkEventHandler(DoWork); 

      if (connect.IsBusy != true) 
       connect.RunWorkerAsync(repl); 
     } 

     private static void DoWork(object sender, DoWorkEventArgs e) 
     { 
      BackgroundWorker worker = sender as BackgroundWorker; 
      try 
      { 
       MergeRepl aspnetdbMergeRepl = e.Argument as MergeRepl; 
       aspnetdbMergeRepl.RunDataSync(); 
       areAllInSync += 1; 
      } 
      catch (Exception) 
      { 
       if (worker != null) worker.CancelAsync(); 
      } 
     } 

Als nächstes Ich würde den ThreadPool für solche Dinge verwenden, die sicherstellen, dass nur eine bestimmte Anzahl von Threads erzeugt wird, um diese Art von Arbeit zu erledigen.

+0

Danke, dass du mir einen besseren Weg gezeigt hast. Ich hatte noch keine Zeit, um darüber zurückzukommen, aber Ihr Beitrag wird sehr hilfreich sein, wenn ich es tue. –

+0

@ mr.Rudolph, eine gute Probe von ThreadPool ?? – Kiquenet

Verwandte Themen