为什么 C# BackgroundWorker 在导入文件时不报告进度?
Why is C# BackgroundWorker not reporting progress when importing a file?
我是多线程的新手,需要帮助。我正在尝试在 C#(WPF 代码隐藏)中使用 BackgroundWorker,以便在通过 BinaryReader 导入文件时更新进度(通过标签内容)。问题是我需要完整的文件才能继续执行程序。因此,我需要知道它何时完成。
我正在尝试将主线程锁定在 while 循环内,直到布尔标志为真,但 ProgressChanged 和 RunWorkerCompleted 方法从未达到,并且在读取字节后主线程似乎被锁定在 while 循环内.你能建议在这种情况下最好的方法是什么吗?下面是我的代码。谢谢!
全球声明:
List<byte> storage_list = new List<byte>();
byte[] storage_byte_array = { (byte)0 };
bool Completed_Flag = false;
部分导入文件处理方法:
byte[] data = Read_File(directory_path);
foreach (byte b in data)
{
//etc
Read_File:
byte[] Read_File(string directory_path)
{
Completed_Flag = false;
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += worker_DoWork;
worker.ProgressChanged += worker_ProgressChanged;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.RunWorkerAsync(directory_path);
while (Completed_Flag == false)
{
System.Threading.Thread.Sleep(100);
}
return storage_byte_array;
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
storage_byte_array = storage_list.ToArray();
Completed_Flag = true;
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
LBL.Content = e.ProgressPercentage;
Console.WriteLine(e.ProgressPercentage);
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
string filename = (string)e.Argument;
FileStream stream = File.OpenRead(@filename);
var length = stream.Length;
var position = 0;
var buffer = new byte[1024];
BinaryReader binReader = new BinaryReader(stream);
while (position < length)
{
int store = binReader.Read(buffer, 0, buffer.Length);
position = position + store;
for (int i = 0; i < buffer.Length; i++)
{
storage_list.Add(buffer[i]);
}
int progressPercentage = Convert.ToInt32(((double)position / length) * 100);
(sender as BackgroundWorker).ReportProgress(progressPercentage);
}
e.Result = storage_list;
}
来自API:
"The call to the ReportProgress method is asynchronous and returns
immediately. The ProgressChanged event handler executes on the thread
that created the BackgroundWorker."
大概是因为您正在这里的主线程上忙着等待,
while (Completed_Flag == false)
{
System.Threading.Thread.Sleep(100);
}
... 对 ReportProgress()
的调用永远没有机会执行。按照您设计它的方式,它基本上是在执行同步操作,那么为什么还要费心使用 BackgroundWorker?
我是多线程的新手,需要帮助。我正在尝试在 C#(WPF 代码隐藏)中使用 BackgroundWorker,以便在通过 BinaryReader 导入文件时更新进度(通过标签内容)。问题是我需要完整的文件才能继续执行程序。因此,我需要知道它何时完成。
我正在尝试将主线程锁定在 while 循环内,直到布尔标志为真,但 ProgressChanged 和 RunWorkerCompleted 方法从未达到,并且在读取字节后主线程似乎被锁定在 while 循环内.你能建议在这种情况下最好的方法是什么吗?下面是我的代码。谢谢!
全球声明:
List<byte> storage_list = new List<byte>();
byte[] storage_byte_array = { (byte)0 };
bool Completed_Flag = false;
部分导入文件处理方法:
byte[] data = Read_File(directory_path);
foreach (byte b in data)
{
//etc
Read_File:
byte[] Read_File(string directory_path)
{
Completed_Flag = false;
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += worker_DoWork;
worker.ProgressChanged += worker_ProgressChanged;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.RunWorkerAsync(directory_path);
while (Completed_Flag == false)
{
System.Threading.Thread.Sleep(100);
}
return storage_byte_array;
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
storage_byte_array = storage_list.ToArray();
Completed_Flag = true;
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
LBL.Content = e.ProgressPercentage;
Console.WriteLine(e.ProgressPercentage);
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
string filename = (string)e.Argument;
FileStream stream = File.OpenRead(@filename);
var length = stream.Length;
var position = 0;
var buffer = new byte[1024];
BinaryReader binReader = new BinaryReader(stream);
while (position < length)
{
int store = binReader.Read(buffer, 0, buffer.Length);
position = position + store;
for (int i = 0; i < buffer.Length; i++)
{
storage_list.Add(buffer[i]);
}
int progressPercentage = Convert.ToInt32(((double)position / length) * 100);
(sender as BackgroundWorker).ReportProgress(progressPercentage);
}
e.Result = storage_list;
}
来自API:
"The call to the ReportProgress method is asynchronous and returns immediately. The ProgressChanged event handler executes on the thread that created the BackgroundWorker."
大概是因为您正在这里的主线程上忙着等待,
while (Completed_Flag == false)
{
System.Threading.Thread.Sleep(100);
}
... 对 ReportProgress()
的调用永远没有机会执行。按照您设计它的方式,它基本上是在执行同步操作,那么为什么还要费心使用 BackgroundWorker?