C# 如何在后台线程中连接到远程服务器上的数据库?
我有一个windows窗体,在该窗体上显示本地数据库中的数据 我还想连接到远程数据库,并从那里显示一些其他数据。。但是,此远程数据库可能已关闭或运行缓慢 我不希望在尝试连接到此远程数据库时UI冻结 因此,对线程或线程安全一无所知,下面是我的第一个示例:C# 如何在后台线程中连接到远程服务器上的数据库?,c#,multithreading,linq-to-sql,C#,Multithreading,Linq To Sql,我有一个windows窗体,在该窗体上显示本地数据库中的数据 我还想连接到远程数据库,并从那里显示一些其他数据。。但是,此远程数据库可能已关闭或运行缓慢 我不希望在尝试连接到此远程数据库时UI冻结 因此,对线程或线程安全一无所知,下面是我的第一个示例: RemoteDataContext rdt; private void GetRemoteDataContext() { rdt = new RemoteDataContext(RemoteServerConnectionString)
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
中):
它是有效的,据我所知,应该没有线程相关的错误。您可能想检查这个类,它会让事情变得更简单
您只需为实际工作、进度报告和线程完成指定委托。您可能需要检查类,这将使事情变得更简单
您只需为实际工作、进度报告和线程完成指定代理。这与我的做法大致相同,但当数据库连接成功并且需要更新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
});
}
这与我的做法是一样的,但是当数据库连接成功并且需要更新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
});
}
哈哈,当我问这个问题的时候,我正把上面的代码抽象成一个类,我称之为“后台工作者”。哈,当我问这个问题时,我正把上面的代码抽象成一个类,我称之为“后台工作者”。我有没有漏掉什么东西,还是和我发布的代码一样?对不起,在格式化代码时,我意外地按了enter键。示例现在完成了。很有趣,但我认为最好将尽可能多的线程处理留给框架:pdefinity,但我敢打赌,迟早您会发现需要额外控制的情况。这时示例将非常有用。我是否遗漏了什么,或者这与我发布的代码相同?抱歉,在格式化代码时,我无意中按了enter键。示例现在完成了。很有趣,但我认为最好将尽可能多的线程处理留给框架:pdefinity,但我敢打赌,迟早您会发现需要额外控制的情况。此时,示例将非常有用。