在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();
}
}
答案 0 :(得分:2)
我只使用一个。
我认为BackgroundWorker允许我执行长时间运行的任务并保持UI响应。
如果我想要多个线程,我使用ThreadPool。
答案 1 :(得分: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用于这样的事情,这将确保只产生特定数量的线程来完成这类工作。
答案 2 :(得分:1)
你需要更具体地说明'flakiness'是什么,它是如何表现出来的。如果我理解正确,那么在没有代理支持的情况下,您正试图手动驱动与RMO类的合并复制。
需要注意的一点是,SQL Express仅支持一个调度程序,因此向其添加多个worker(挂起请求)不会产生太大影响,它们只会堆积在可运行队列中并争夺一个CPU运行它们。
其次,我不确定RMO复制类(我假设你使用它)支持在多个并行实例中进行同步,所以我可能没有必要做更多的事情,每个db只有一个BackgroundWorker(我可能是这个错了,我不是任何一个RMO专家。