【发布时间】:2021-04-01 13:27:08
【问题描述】:
我正在运行代码以从 pdf 文件中读取文本,然后创建一个 WordCloud。为了通知用户该过程正在进行中,我将BackgroundWorker 添加到我的表单中,显示image 表示正在加载。跨不同线程操作时出现错误。
Private Sub ButtonCreate_Click(sender As Object, e As EventArgs) Handles ButtonCreate.Click
bTextEmpty = False
ListView1.Items.Clear()
ResultPictureBox.Image = Nothing
If ListBox1.SelectedIndex > -1 Then
For Each Item As Object In ListBox1.SelectedItems
Dim ItemSelected = CType(Item("Path"), String)
Dim myTempFile As Boolean = File.Exists(ItemSelected + "\Words.txt")
If myTempFile = False Then
'when we load the form we first call the code to count words in all files in a directory
'lets check if the folder exists
If (Not System.IO.Directory.Exists(ItemSelected)) Then
Dim unused = MsgBox("The archive " + ItemSelected.Substring(ItemSelected.Length - 5, Length) + " was not found",, Title)
Exit Sub
Else
Call CreateWordList(ItemSelected)
End If
End If
'if the words file is empty we cant create a cloud so exit the sub
If bTextEmpty = True Then Exit Sub
'then we fill the wordcloud and Listview from the created textfile
Call CreateMyCloud(ItemSelected + "\Words.txt")
Next
Else
Dim unused = MsgBox("You have to choose an Archive to create the Word Cloud",, Title)
End If
Size = New Drawing.Size(1400, 800)
End Sub
我把上面的代码放在一个 Private Sub 中,并从我的BackgroundWorker 中调用它。错误发生在这一行:If ListBox1.SelectedIndex > -1 Then
在尝试了建议的代码后,我再次遇到同样的错误:
Public Sub CreateMyCloud(ByVal sourcePDF As String)
Dim WordsFreqList As New List(Of WordsFrequencies)
For Each line As String In File.ReadLines(sourcePDF)
Dim splitText As String() = line.Split(","c)
If splitText IsNot Nothing AndAlso splitText.Length = 2 Then
Dim wordFrq As New WordsFrequencies
Dim freq As Integer
wordFrq.Word = splitText(0)
wordFrq.Frequency = If(Integer.TryParse(splitText(1), freq), freq, 0)
WordsFreqList.Add(wordFrq)
End If
Next
If WordsFreqList.Count > 0 Then
' Order the list based on the Frequency
WordsFreqList = WordsFreqList.OrderByDescending(Function(w) w.Frequency).ToList
' Add the sorted items to the listview
WordsFreqList.ForEach(Sub(wf)
error -> ListView1.Items.Add(New ListViewItem(New String() {wf.Word, wf.Frequency.ToString}, 0))
End Sub)
End If
Dim wc As WordCloudGen = New WordCloudGen(600, 400)
Dim i As Image = wc.Draw(WordsFreqList.Select(Function(wf) wf.Word).ToList, WordsFreqList.Select(Function(wf) wf.Frequency).ToList)
ResultPictureBox.Image = i
End Sub
【问题讨论】:
-
将代码主体移动到另一个方法中。如果没有选择任何项目,那么您根本不启动工作人员。
-
一般来说,从 UI 线程(按钮单击处理程序)中,您应该将要处理的项目从 ListBox 收集到
List(Of String),然后将其传递给RunWorkerAsync()。这可以通过DoWorkEventArgs参数在DoWork()处理程序中检索,如e.Argument。 -
当你想更新 UI 时,使用
ReportProgress()方法,它会触发ProgressChanged()事件。从该事件中更新 UI 是安全的。同样,当 BackgroundWorker 完成后,RunWorkerCompleted()事件将触发,您可以在其中对 UI 进行其他更新。 -
@HansPassant 你能告诉我那会是什么样子吗?
标签: vb.net backgroundworker word-cloud