ComboBox在多线程中不可读

时间:2014-04-21 16:14:43

标签: vb.net multithreading winforms

我正在尝试构建一个连接到几个数据库的小型应用程序,以便将数据从一个数据库移动到另一个数据库,操作和验证数据是否移动。我已经完成了所有工作,但是想将大部分工作添加到第二个线程中,以便初始窗口仍然可用。

到目前为止,我的大部分工作正常,除了一个讨厌的位。我允许用户从MSSQL Server上的数据库列表中选择数据库。如果没有线程,程序可以毫无问题地读取组合框的文本。一旦我添加了线程,它就无法读取组合框的文本。读取包含servername / username / password的文本框没有问题,只需使用这一个组合框。下面的代码位于一个处理我所有数据库函数的类中。组合框位于运行应用程序时启动的主窗体(frmMain)上。 frmMain是应用程序的默认表单。

没有线程我就是这样做的。

Me._sqlDB = New sqlDatabase
Me._sqlDB.DBServer = frmMain.txtServer.Text
Me._sqlDB.DBUsername = frmMain.txtUser.Text
Me._sqlDB.DBPassword = frmMain.txtPassword.Text
Me._sqlDB.DBDatabase = frmMain.cboSQLDatabase.Text

当我添加线程时,它无法从组合框中读取(以及由于非线程安全调用而导致的许多其他问题)。我做了一些研究,并在一些代表中添加并调用。这解决了我遇到的其他问题,但组合框仍然无法读取。

我创建了一个带委托的函数来读取组合框,希望它是一个线程相关的问题,但仍然没有运气。数据库连接设置代码在我上面提到的数据库类中,GetDatabaseName函数是主窗体(frmMain)。

'Database Connection Setup
Me._sqlDB = New sqlDatabase
Me._sqlDB.DBServer = frmMain.txtServer.Text
Me._sqlDB.DBUsername = frmMain.txtUser.Text
Me._sqlDB.DBPassword = frmMain.txtPassword.Text
Me._sqlDB.DBDatabase = frmMain.GetDatabaseName

'GetDatabaseName Function for Connection String Setup
Delegate Function GetDatabaseNameDel() As String

Public Function GetDatabaseName() As String
    Dim DBName As String = ""
    If Me.cboSQLDatabase.InvokeRequired Then
        DBName = Me.Invoke(New GetDatabaseNameDel(AddressOf GetDatabaseName))
    Else
        DBName = Me.cboSQLDatabase.Text
    End If
    Return DBName
End Function

我尝试了几种组合框属性,包括SelectedItem,SelectedText和Text。调用GetDatabaseName函数时,它们都没有任何值。实际上,当在调试模式下运行并暂停代码执行时,Visual Studio会显示组合框中没有任何内容(Count = 0,Items集合为空)。

使用SqlDataReader填充组合框,该SqlDataReader从服务器读取数据库名称列表。

我也尝试更改设置以使用BackgroundWorker,但我得到了相同的结果。

关于为什么组合框在作为单独的线程运行时显示为空的任何想法?


通过更多的研究,我找到了一个可能的解决方案,但它看起来真的很笨拙。如果我改变对函数的调用来使用它:

Me._sqlDB.DBDatabase = CType(My.Application.OpenForms.Item("frmMain"), frmMain).GetDatabaseName

它有效,但对于这个问题,这似乎是一个非常奇怪的解决方法。有没有更好的方法来引用活动表单上的控件?

0 个答案:

没有答案