#wpf #vb.net #multithreading #silverlight #user-interface
#wpf #vb.net #многопоточность #silverlight #пользовательский интерфейс
Вопрос:
Добрый вечер,
Ниже приведен код, который я использовал для чтения файлов и папок с диска и т.д.
Public Class LoadingBox
Public counter As ULong
Public OpenRecords As New Dictionary(Of String, MainWindow.records)
Public Path As String
Public Diskname As String
Private WithEvents BKWorker As New BackgroundWorker()
Public Sub New(ByVal _Path As String, ByVal _Diskname As String)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Path = _path
Diskname = _diskname
End Sub
Private Sub GetStructure(ByVal tempdir As String, ByVal ParentID As String, ByVal DiskName As String)
Dim maindir As DirectoryInfo = My.Computer.FileSystem.GetDirectoryInfo(tempdir)
For Each Dir As DirectoryInfo In maindir.GetDirectories
Try
Dim d As New MainWindow.records
d.Filename = Dir.Name
d.Folder = True
d.Rowid = Date.UtcNow.ToString() counter.ToString()
d.Size = 0
d.ParentID = ParentID
d.DiskName = DiskName
d.DateCreated = Dir.CreationTimeUtc
d.DateModified = Dir.LastWriteTimeUtc
OpenRecords.Add(d.Rowid, d)
'Label1.Content = "Processing: " Dir.FullName
BKWorker.ReportProgress(0, Dir.FullName)
counter = counter 1
GetStructure(Dir.FullName, d.Rowid, DiskName)
Catch ex As Exception
End Try
Next
For Each fil As FileInfo In maindir.GetFiles
Try
Dim d As New MainWindow.records
d.Filename = fil.Name
d.Folder = False
d.Rowid = Date.UtcNow.ToString() counter.ToString()
d.Size = fil.Length
d.ParentID = ParentID
d.DiskName = DiskName
d.DateCreated = fil.CreationTimeUtc
d.DateModified = fil.LastWriteTimeUtc
OpenRecords.Add(d.Rowid, d)
'Label1.Content = "Processing: " fil.FullName
BKWorker.ReportProgress(0, fil.FullName)
counter = counter 1
Catch ex As Exception
End Try
Next
End Sub
Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
counter = 0
BKWorker.WorkerReportsProgress = True
AddHandler BKWorker.DoWork, AddressOf BKWorker_Do
AddHandler BKWorker.ProgressChanged, AddressOf BKWorker_Progress
AddHandler BKWorker.RunWorkerCompleted, AddressOf BKWorker_Completed
BKWorker.RunWorkerAsync()
'GetStructure(Path, "0", Diskname)
End Sub
Private Sub BKWorker_Do(ByVal sender As Object, ByVal e As DoWorkEventArgs)
'Throw New NotImplementedException
GetStructure(Path, "0", Diskname)
End Sub
Private Sub BKWorker_Progress(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
'Throw New NotImplementedException
Label1.Content = "Processing: " e.UserState.ToString()
If ProgressBar1.Value = 100 Then
ProgressBar1.Value = 0
End If
ProgressBar1.Value = ProgressBar1.Value 1
End Sub
Private Sub BKWorker_Completed(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
'Throw New NotImplementedException
MessageBox.Show("Completed")
Me.Close()
End Sub
End Class
Однако проблема в том, что фоновый поток способен читать файлы очень быстро, но поток пользовательского интерфейса не в состоянии поддерживать скорость с ним, не могли бы вы, пожалуйста, посоветовать мне, как я могу решить эту проблему.
Ответ №1:
Вам почти никогда не захочется сообщать о прогрессе по каждому отдельному элементу, когда вы перебираете такое количество элементов.
Я бы посоветовал найти некоторое разумное количество файлов, чтобы подождать, прежде чем сообщать о прогрессе. Каждый 5-й или каждый 10-й или так далее. Вероятно, вы захотите взглянуть на то, каково ваше обычное количество файлов. Другими словами, если вы обычно обрабатываете только 25 файлов, вы, вероятно, не хотите обновлять только каждые 10 файлов. Но если вы обычно обрабатываете 25000 файлов, вы могли бы, возможно, даже обновлять только каждые 100 файлов.
Комментарии:
1. Большое вам спасибо за быстрый ответ. Решаемая путем следования вашим советам.
Ответ №2:
Одним из быстрых ответов было бы сообщать о прогрессе только по истечении определенного количества времени, таким образом, если за это время было обработано 10 файлов, пользовательский интерфейс не пытается обновлять по одному каждый. Если все обрабатывается так быстро, то вам действительно не нужно обновлять пользователя для каждого отдельного файла.
Также на заметку, если ваша панель выполнения на самом деле не сообщает о прогрессе от 0 до 100%, вы можете просто установить для ее IsIndeterminate
свойства значение true вместо увеличения процента и последующего сброса его обратно на 0.
Комментарии:
1. Большое вам спасибо за быстрый ответ. Решаемая путем следования вашим советам, а также отметил IsIndeterminate, спасибо за информативность.