我有一个WPF应用程序,用户在一些文本框中输入数据库信息。用户单击“连接”后,将从用户输入的内容创建连接字符串并建立连接。我注意到,如果用户输入错误的信息,应用程序将挂起直到连接超时。挂起指用户无法与应用程序的其他部分进行交互。
我的目标是在测试连接字符串时保持应用程序响应。
我认为将此工作流程放在不同的线程上是一个好的解决方案。我的想法是,在线程运行时禁用可能需要数据库连接的任何内容。一旦线程返回(并已确认连接字符串有效),我将重新启用所有内容。否则,保持所有内容禁用。
但是,Thread类没有线程完成时的事件通知(或者至少我不知道有这样的)。我还使用过BackgroundWorker类。这个方法更好。然而,当触发RunWorkerCompletedEventHandler事件且连接字符串无效时,我会收到以下异常:
"The calling thread cannot access this object because a different thread owns it."
这可能是因为完成事件处理程序被触发时连接仍未超时。
有人有什么想法吗?或者我应该不尝试将数据库连接多线程化?
我正在做的代码概述:
我的目标是在测试连接字符串时保持应用程序响应。
我认为将此工作流程放在不同的线程上是一个好的解决方案。我的想法是,在线程运行时禁用可能需要数据库连接的任何内容。一旦线程返回(并已确认连接字符串有效),我将重新启用所有内容。否则,保持所有内容禁用。
但是,Thread类没有线程完成时的事件通知(或者至少我不知道有这样的)。我还使用过BackgroundWorker类。这个方法更好。然而,当触发RunWorkerCompletedEventHandler事件且连接字符串无效时,我会收到以下异常:
"The calling thread cannot access this object because a different thread owns it."
这可能是因为完成事件处理程序被触发时连接仍未超时。
有人有什么想法吗?或者我应该不尝试将数据库连接多线程化?
我正在做的代码概述:
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
dbTool = new DBTool();
// Create the connection string
e.Result = dbTool.connectToDB(); // connectToDB() returns a bool (true if connection established)
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// connectToDB() returns a bool (true if connection established)
if(e.Result == true) // Trying to read e.Result here throws the exception
{
// e.Error and e.Cancel should be checked first
// However, I would like the thread to finish before
// this event is fired
}
if (e.Error != null)
{
Console.WriteLine(e.Error.Message);
}
}
Console.WriteLine()
和e.Error
都不应该抛出此异常。但更新UI控件可能会引发异常。 - Sean URunWorkerCompletedEventArgs
的Error
属性不为 null,访问其Result
属性将引发异常。 - Sean UResult
属性之前完成,即在触发bw_RunWorkerCompleted
事件之前。 - Chris DargisBackgroundWorker
直到完成、被取消或引发异常才会触发RunWorkerCompleted
。您可以通过在RunWorkerCompleted
处理程序中设置断点,然后查看并行堆栈窗口来验证这一点。 - Sean U