C# 如何在后台线程中连接到远程服务器上的数据库?

C# 如何在后台线程中连接到远程服务器上的数据库?,c#,multithreading,linq-to-sql,C#,Multithreading,Linq To Sql,我有一个windows窗体,在该窗体上显示本地数据库中的数据 我还想连接到远程数据库,并从那里显示一些其他数据。。但是,此远程数据库可能已关闭或运行缓慢 我不希望在尝试连接到此远程数据库时UI冻结 因此,对线程或线程安全一无所知,下面是我的第一个示例: RemoteDataContext rdt; private void GetRemoteDataContext() { rdt = new RemoteDataContext(RemoteServerConnectionString)

我有一个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
中):


它是有效的,据我所知,应该没有线程相关的错误。

您可能想检查这个类,它会让事情变得更简单


您只需为实际工作、进度报告和线程完成指定委托。

您可能需要检查类,这将使事情变得更简单


您只需为实际工作、进度报告和线程完成指定代理。

这与我的做法大致相同,但当数据库连接成功并且需要更新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,但我敢打赌,迟早您会发现需要额外控制的情况。此时,示例将非常有用。