Как я могу подключиться к базе данных на удаленном сервере в фоновом потоке? - PullRequest
0 голосов
/ 03 апреля 2009

У меня есть форма Windows, в которой я отображаю данные из локальной базы данных.

Я также хотел бы подключиться к удаленной базе данных и отобразить оттуда некоторые другие данные ... однако эта удаленная база данных может быть недоступна или работать медленно.

Я не хочу, чтобы пользовательский интерфейс зависал при попытке подключиться к этой удаленной базе данных.

Итак, ничего не зная о многопоточности или безопасности потоков, вот мой пример:

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();

И это работает, и, насколько я понимаю, не должно быть ошибок, связанных с многопоточностью.

Ответы [ 2 ]

2 голосов
/ 03 апреля 2009

Возможно, вы захотите проверить класс BackgroundWorker , это облегчит задачу.

Вам нужно только указать делегатов для фактической работы, для отчетов о ходе выполнения и завершения потока.

1 голос
/ 03 апреля 2009

Это похоже на то, как я это сделаю, но у вас возникнет проблема с многопоточным доступом, когда ваше соединение с базой данных будет успешным, и вам нужно обновить свой интерфейс. Как подсказывает 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   
    });    
}
...