【发布时间】:2014-06-25 05:33:20
【问题描述】:
我有一个 WPF 应用程序,在主窗体中,允许用户选择几个文件 (Excel),然后单击一个按钮进行数据提取并将它们上传到数据库。一切正常。
现在我想实现一个忙碌指示器。
所以我所做的是,声明一个 BackgroundWorker 线程并将我的数据库上传(这需要时间)作为后台线程。当线程启动和完成时,相应地设置忙碌指示符。问题出在我的上传过程中,我访问剪贴板以打印一些消息。所以我遇到了以下明显的错误。
"Current thread must be set to single thread apartment (STA) mode before OLE calls can be made."
BackgroundWorker 默认为 MTA。那么解决这个问题的最佳方法是什么?
代码:
Public WithEvents BgWorker As BackgroundWorker = New BackgroundWorker()
Private Sub MainWindow_Loaded() Handles Me.Loaded
AddHandler BgWorker.DoWork, AddressOf ExtractData
AddHandler BgWorker.RunWorkerCompleted, AddressOf BgWorker_RunWorkerCompleted
End Sub
Private Sub btnExtract_Click(sender As Object, e As RoutedEventArgs)
.....
Try
.....
Me.busyIndicator.IsBusy = True
BgWorker.RunWorkerAsync(Me.cmbFormats.SelectedItem.ToString.Trim())
Catch ex As Exception
Utility.Message.ErrorMessage(ex)
End Try
End Sub
完成的事件:
Private Sub BgWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
busyIndicator.IsBusy = False
End Sub
工作:
Private Sub ExtractData(sender As Object, e As DoWorkEventArgs)
Dim exformat As IExtractor = New FormatFactory().CreateInstance(e.Argument.ToString())
If (exformat.FeedToDb(filename)) Then
Utility.Message.SuccessMessage("Successfully Extracted to database")
Else
End If
End Sub
Utility.Message.SuccessMessage :
Public Shared Sub SuccessMessage(msg As String)
Dim M As New Text.StringBuilder
M.AppendLine()
M.AppendLine(msg)
M.AppendLine()
Clipboard.Clear() 'problem with MTA
Clipboard.SetText(M.ToString)
MsgBox(M.ToString, MsgBoxStyle.Information, "FF IT")
End Sub
【问题讨论】:
-
只需将 SuccesMessage() 调用移至 RunWorkerCompleted 事件处理程序。使用 e.Result 报告成功状态。
-
问题是我在从 FeedToDb 内部调用的其他方法中有更多这样的调用。
标签: .net wpf multithreading com sta