Есть ли ограничение на фоновых работников? Технический или здравый смысл - PullRequest
2 голосов
/ 16 июля 2009

В Program.cs у меня есть метод ниже, который проверяет и синхронизирует 5 БД SQL с центральным сервером. Каждый из них отделен от другого, поэтому я решил ускорить загрузку моей программы, запустив их все одновременно.

К сожалению, работать один раз очень плохо, а потом - нет. Локальная БД - SQLExpress 2005, а центральная БД - SQL Server Standard 2005.

Существует ли ограничение на количество соединений, которое может иметь одно из них? Как насчет Фоновых Рабочих, я могу только так много бегать одновременно? Я уверен, что есть гораздо более красноречивый способ сделать это, я хотел бы услышать (увидеть) их.

Так я называю это в Main () в 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();
        }

    }

Ответы [ 3 ]

2 голосов
/ 16 июля 2009

Ну, для начала, и мне очень жаль это говорить, но ваш код причиняет мне боль ...

Весь этот беспорядок можно переписать так:

        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 для подобных вещей, что обеспечит создание только определенного числа потоков для выполнения такой работы.

2 голосов
/ 16 июля 2009

Я использую только один.

Я полагаю, что BackgroundWorker позволяет мне выполнять долгосрочную задачу и поддерживать отзывчивость интерфейса.

Если я хочу несколько потоков, я использую ThreadPool.

1 голос
/ 16 июля 2009

Вы должны быть более конкретны, что такое «вялость», как она проявляется. Если я правильно понимаю, вы пытаетесь вручную запустить репликацию слиянием с классами RMO в отсутствие поддержки агента.

Следует отметить, что SQL Express поддерживает только один планировщик, поэтому добавление к нему нескольких рабочих (ожидающих запросов) не будет иметь большого значения, они просто будут накапливаться в работающей очереди и бороться за один ЦП. запустить их.

Во-вторых, я не уверен, что классы репликации RMO (которые, как я полагаю, вы используете) поддерживают синхронизацию в нескольких параллельных экземплярах, поэтому я, вероятно, нет смысла делать больше, чем один BackgroundWorker на дБ неправильно в этом, я не эксперт RMO ни в коем случае).

...