为什么 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;
    }

为什么 C# 后台工作者在导入文件时不报告进度

从 API :

"对 ReportProgress 方法的调用是异步的,并返回 马上。ProgressChanged 事件处理程序在线程上执行 创造了背景工作者。

大概正在发生的事情是,由于您在这里忙于等待主线程,

while (Completed_Flag == false)
{
   System.Threading.Thread.Sleep(100);
}

。对ReportProgress()的调用永远没有机会执行。你构建它的方式,无论如何它基本上都是在执行同步操作,那么为什么要打扰 BackgroundWorker 呢?