为什么 C# 后台工作者在导入文件时不报告进度
本文关键字:报告 文件 导入 后台 工作者 为什么 | 更新日期: 2023-09-27 17:57:25
我是多线程新手,我需要帮助。我正在尝试使用 C# 中的 BackgroundWorker (WPF 代码隐藏),以便在通过 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 :
"对 ReportProgress 方法的调用是异步的,并返回 马上。ProgressChanged 事件处理程序在线程上执行 创造了背景工作者。
大概正在发生的事情是,由于您在这里忙于等待主线程,
while (Completed_Flag == false)
{
System.Threading.Thread.Sleep(100);
}
。对ReportProgress()
的调用永远没有机会执行。你构建它的方式,无论如何它基本上都是在执行同步操作,那么为什么要打扰 BackgroundWorker 呢?