Async Await Progress Reporting Not Working

自作多情 提交于 2020-06-12 06:39:12

问题


I have a C# WPF program that opens a file, reads it line by line, manipulates each line then writes the line out to another file. That part worked fine. I wanted to add some progress reporting so I made the methods async and used await with progress reporting. The progress reporting is super simple - just update a label on the screen. Here is my code:

async void Button_Click(object sender, RoutedEventArgs e)
{
    OpenFileDialog openFileDialog = new OpenFileDialog();
    openFileDialog.Title = "Select File to Process";
    openFileDialog.ShowDialog();
    lblWaiting.Content = "Please wait!";
    var progress = new Progress<int>(value => { lblWaiting.Content = "Waiting "+ value.ToString(); });
    string newFN = await FileProcessor(openFileDialog.FileName, progress);
    MessageBox.Show("New File Name " + newFN);
} 

static async private Task<string> FileProcessor(string fn, IProgress<int> progress)
{
    FileInfo fi = new FileInfo(fn);
    string newFN = "C:\temp\text.txt";

    int i = 0;

    using (StreamWriter sw = new StreamWriter(newFN))
    using (StreamReader sr = new StreamReader(fn))
    {
        string line;

        while ((line = sr.ReadLine()) != null)
        {
            //  manipulate the line 
            i++;
            sw.WriteLine(line);
            // every 500 lines, report progress
            if (i % 500 == 0)
            {
                progress.Report(i);
            }
        }
    }
    return newFN;
}

Any help, advice or suggestions would be greatly appreciated.


回答1:


Just marking your method as async has pretty much no effect on execution flow, because you're not yielding the execution ever.

Use ReadLineAsync instead of ReadLine and WriteLineAsync instead of WriteLine:

static async private Task<string> FileProcessor(string fn, IProgress<int> progress)
{
    FileInfo fi = new FileInfo(fn);
    string newFN = "C:\temp\text.txt";

    int i = 0;

    using (StreamWriter sw = new StreamWriter(newFN))
    using (StreamReader sr = new StreamReader(fn))
    {
        string line;

        while ((line = await sr.ReadLineAsync()) != null)
        {
            //  manipulate the line 
            i++;
            await sw.WriteLineAsync(line);
            // every 500 lines, report progress
            if (i % 500 == 0)
            {
                progress.Report(i);
            }
        }
    }
    return newFN;
}

That will yield the UI thread and allow the label to be redrawn.

PS. The compiler should have raised a warning with your initial code, because you have an async method which does not use await.



来源:https://stackoverflow.com/questions/46498581/async-await-progress-reporting-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!