2

Program.cs には、5 つの SQL データベースをチェックして中央サーバーと同期する以下のメソッドがあります。それぞれが別のものであるため、すべてを同時に実行することで、プログラムのロード時間を短縮することを考えました。

残念ながら、一度は非常に不安定で、次はそうではありません。ローカル DB は SQLExpress 2005 で、中央 DB は SQL Server Standard 2005 です。

それらのいずれかが持つことができる接続の数に制限はありますか? バックグラウンド ワーカーはどうですか。一度に実行できる数は限られていますか? これを行うにはもっと雄弁な方法があると確信しています。それらを聞いて(見て)みたいです。

これは、Program.cs の Main() でこれを呼び出す方法です -->

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

    }
4

3 に答える 3

2

私は1つだけを使用します。

BackgroundWorker は、長時間実行されるタスクを実行し、UI の応答性を維持できるようにするためにあると考えています。

複数のスレッドが必要な場合は、ThreadPool を使用します。

于 2009-07-15T21:10:50.407 に答える
2

まず始めに、これを言って申し訳ありませんが、あなたのコードは私の目を傷つけます...

この混乱全体は、次のように書き直すことができます。

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

次に、このような作業には ThreadPool を使用します。これにより、この種の作業を行うために特定の数のスレッドのみが生成されるようになります。

于 2009-07-15T21:14:11.803 に答える
1

「フレークネス」とは何か、それがどのように現れるのかをより具体的にする必要があります。私の理解が正しければ、RMO クラスを使用してマージ レプリケーションを手動で実行しようとしていますが、エージェント サポートが不足しています。

注意すべきことの 1 つは、SQL Express がサポートするスケジューラは 1 つだけであるため、複数のワーカー (保留中の要求) を追加しても大きな違いはありません。それらは実行可能なキューに積み上げられ、1 つの CPU がそれらを実行するために戦うだけです。 .

2 つ目は、RMO レプリケーション クラス (使用していると思われる) が複数の並列インスタンスでの同期をサポートしているかどうかわからないため、db ごとに 1 つの BackgroundWorker よりも多くのことを行う意味がない可能性があります (これについては間違っている可能性があります)。 1 つ、私は決して RMO の専門家ではありません)。

于 2009-07-15T21:13:41.150 に答える