2

Dans Program.cs J'ai la méthode ci-dessous qui vérifie et la Synchronisation 5 SQL DB avec le serveur central. Chacun étant séparé de l'autre, j'ai pensé accélérer le temps de chargement de mon programme en les faisant tous tourner en même temps.Y a-t-il une limite pour les travailleurs en arrière-plan? Technique ou sens commun

Malheureusement, il est très feuilletant de travailler une fois, puis pas la suivante. La base de données locale est SQLExpress 2005 et la base de données centrale est SQL Server Standard 2005.

Y at-il une limite sur le nombre de connexions que l'un de ces deux peut avoir? Qu'en est-il des travailleurs de fond, puis-je avoir autant de coureurs à la fois? Je suis sûr qu'il y a une façon beaucoup plus éloquente de le faire, j'aimerais les entendre.

Voilà comment j'appelle cela dans Main() dans 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

Pour commencer, j'ai compris que mon temps était mauvais et causant une partie du problème. –

Répondre

1

Vous avez besoin d'être plus précis sur ce qu'est le "flakiness", comment il se manifeste. Si je comprends bien, vous essayez de conduire manuellement une réplication de fusion avec des classes RMO, en l'absence de support de l'Agent. Une chose à noter est que SQL Express ne prend en charge qu'un seul planificateur. Par conséquent, l'ajout de plusieurs travailleurs (demandes en attente) ne fera pas beaucoup de différence, ils s'accumuleront dans la file d'attente exécutable et se battront pour l'un. CPU pour les exécuter. Deuxièmement, je ne suis pas sûr que les classes de réplication RMO (que je suppose que vous utilisez) supportent la synchronisation dans plusieurs instances parallèles, donc je n'ai probablement aucun intérêt à faire plus d'un BackgroundWorker par db (je peux se tromper sur celui-ci, je ne suis pas un expert RMO de toute façon).

+0

Le flakiness je crois est parce que vous l'avez cloué. J'essayais de "tricher". J'utilise RMO et la fusion synchrone des données avec elle. Je pensais pouvoir les faire tous courir mais ça ne semble pas le cas maintenant. –

2

J'utilise un seul.

Je pense que BackgroundWorker est là pour me permettre d'exécuter une tâche de longue durée et de garder l'interface utilisateur sensible.

Si je veux plusieurs threads, j'utilise le ThreadPool.

+0

Cela a du sens. Y at-il une raison technique que vous ne pouvez pas utiliser plusieurs? Ne vous inquiétez pas, on me dit que ce n'est pas une bonne pratique, je me demandais juste s'il y avait une autre raison. Merci! –

+0

BackgroundWorker fournit un mécanisme pour passer des messages entre l'interface utilisateur et votre tâche d'arrière-plan d'une manière thread-safe. Si vous avez besoin de ce genre d'interactivité, utilisez BackgroundWorkers. Si vous ne le faites pas, la création d'un thread à partir de ThreadPool est plus simple (problèmes d'accès simultanés). –

2

Eh bien, pour commencer et je suis désolé de dire cela, mais votre code blesse mes yeux ...

Ce désordre entier peut être réécrite comme ceci:

 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(); 
      } 
     } 

Ensuite, J'utiliserais le ThreadPool pour ce genre de choses, ce qui garantirait que seul un nombre spécifique de threads est créé pour faire ce genre de travail.

+0

Merci de me montrer un meilleur moyen. Je n'avais pas eu le temps d'y revenir mais votre post sera très utile si je le fais. –

+0

@ mr.Rudolph, un bon échantillon de ThreadPool ?? – Kiquenet