等待任务 - 如何在进度条为 运行 的同时写入文本文件?

Await Task - How to write a text file meantime the progress bar is running?

场景:一个进程写入一个文本文件,同时另一个进程用进度条显示当前情况。最后一个消息框显示 Done

怎么了?代码不显示进度情况,只在最后显示 我可以看到 100% 的进度条和消息框。

为什么会出现这个问题?

这是我的代码

<Button Command="{Binding MyCommand2}" Content="Click Me" Margin="10,10,670,321"/>
        
<ProgressBar HorizontalAlignment="Left" Height="17" Margin="172,200,0,0" VerticalAlignment="Top" Width="421" Maximum="20" Value="{Binding Prog_bar_value}"/>



public int ncount = 0;

private int _prog_bar_value;
public int Prog_bar_value
{
    get { return _prog_bar_value; }
    set
    {
        _prog_bar_value = value;
        base.OnPropertyChanged("Prog_bar_value");
    }
}



private async void startButton_Click()
{
    await WriteTextFile(); // The 2 methods must be separated.
    await Progress();

    MessageBox.Show("Done");  //here we're on the UI thread.
}


async Task Progress()
{
    await Task.Run(() =>
    {
        Prog_bar_value = ncount;
    });
}


async Task WriteTextFile()
{
    await Task.Run(Exec_WriteTextFile);
}


void Exec_WriteTextFile()
{
    using (StreamWriter sw = File.CreateText(@"C:\temp\Abc.txt"))
    {
        for (int i = 0; i < 20; i++)
        {
            sw.WriteLine("Values {0} Time {1} ", i.ToString(), 
            DateTime.Now.ToString("HH:mm:ss"));
            ncount = i;
            Thread.Sleep(500); //this is only for create a short pause
        }
    }
}

很好用

await WriteTextFile();

您等待该方法(好的,实际上是返回的任务)完成。 完成后设置进度条值。

你可以用 IProgress<T>/Progress<T> 来处理。

private async void startButton_Click()
{
    var progress = new Progress<int>(value => Prog_bar_value = value);
    await WriteTextFile(progress); 

    MessageBox.Show("Done"); 
}

Task WriteTextFile(IProgress<int> progress)
{
    return Task.Run(() => Exec_WriteTextFile(progress));
}

void Exec_WriteTextFile(IProgress<int> progress)
{
    using (StreamWriter sw = File.CreateText(@"C:\temp\Abc.txt"))
    {
        for (int i = 0; i < 20; i++)
        {
            sw.WriteLine("Values {0} Time {1} ", i.ToString(), 
            DateTime.Now.ToString("HH:mm:ss"));
            progress.Report(i);
            Thread.Sleep(500); //this is only for create a short pause
        }
    }
}