我有一个Windows窗体,我在其上显示本地数据库中的数据。
我还要连接到远程数据库,并从那里显示一些其他数据..但是,这个远程数据库可能已关闭或缓慢。
当我尝试连接到此远程数据库时,我不希望UI冻结。
所以对线程或线程安全一无所知,这是我的一个例子:
RemoteDataContext rdt;
private void GetRemoteDataContext() {
rdt = new RemoteDataContext(RemoteServerConnectionString);
}
private void FillFromRemoteDataContext() {
lblTest.text = rdt.TestTable.First().TestField;
}
private void Form1_Shown(object sender, EventArgs e) {
Thread t = new Thread(new ThreadStart(new delegate {
try {
GetRemoteDataContext();
FillFromRemoteDataContext();
} catch { } // ignore connection errors, just don't display data
);
t.Start;
}
所以你应该能够从中得知我想要实现的目标。
我的问题是,正确的方法是什么?
更新:谢谢大家,我现在(Form1Shown
):
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler((sender, e) => {
e.Result = null;
try {
e.Result = new RemoteDataContext(RemoteServerConnectionString);
} catch { } // ignore connection errors, just don't display data
});
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler((sender, e) => {
if (e.Result != null) {
rdt = (RemoteDataContext)e.Result;
FillFromRemoteDataContext();
}
});
bw.RunWorkerAsync();
它有效,据我所知,应该没有与线程相关的错误。
答案 0 :(得分:2)
您可能想要查看BackgroundWorker课程,这会让事情变得更容易。
您只需为实际工作,进度报告和线程完成指定委托。
答案 1 :(得分:1)
这就是我如何做到这一点,但是当数据库连接成功并且您需要更新UI时,您将遇到的问题是跨线程访问。正如CMS建议您可以使用BackgroundWorker类并让它为您处理跨线程编组。我倾向于采用更细粒度的控制,我会将你的例子实现为:
RemoteDataContext rdt;
private void GetRemoteDataContext() {
rdt = new RemoteDataContext(RemoteServerConnectionString);
}
private void FillFromRemoteDataContext() {
if (lblTest.Dispatcher.Thread != Thread.CurrentThread) {
lblTest.Dispatcher.Invoke(delegate { lblTest.text = rdt.TestTable.First().TestField});
}
else {
lblTest.text = rdt.TestTable.First().TestField;
}
}
private void Form1_Shown(object sender, EventArgs e) {
ThreadPool.QueueUserWorkItem(delegate {
try {
GetRemoteDataContext();
FillFromRemoteDataContext();
} catch { } // ignore connection errors, just don't display data
});
}