2

在 Program.cs 中,我有以下方法正在检查以及将 5 个 SQL 数据库与中央服务器同步。每一个都是相互独立的,所以我想通过让它们同时运行来加快我的程序的加载时间。

不幸的是,一次工作非常不稳定,下一次就不行了。本地数据库是 SQLExpress 2005,中央数据库是 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

我只用一个。

我认为 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 类的合并复制,而缺少代理支持。

需要注意的一点是 SQL Express 仅支持一个调度程序,因此向其中添加多个工作程序(待处理的请求)不会有太大的不同,它们只会堆积在可运行队列中并争夺一个 CPU 来运行它们.

其次,我不确定 RMO 复制类(我假设您使用)是否支持在多个并行实例中进行同步,所以我可能没有必要为每个数据库只做一个 BackgroundWorker(我可能错了)一,无论如何我都不是 RMO 专家)。

于 2009-07-15T21:13:41.150 回答