使用异步和等待实时更新数据

我已经尝试了这个答案中提到的代码:https://stackoverflow.com/a/27089652/

它运行良好,我想用它在 for 循环中运行 PowerShell 脚本。 GUI最初冻结然后我尝试了这个答案中提到的代码:https://stackoverflow.com/a/35735760/

现在,当 PowerShell 脚本在后台运行时,GUI 不会冻结,尽管在 for 循环完成之前文本框中没有任何更新。我想看到实时更新的结果。这是我正在运行的代码:

        private async void run_click(object sender,RoutedEventArgs e)
        {
            Text1.Text = "";
            
            await Task.Run(() => PS_Execution(Text1));

        }

        internal async Task PS_Execution(TextBox text)
        {

            PowerShell ps = PowerShell.Create();
            ps.AddScript(script.ToString());

            {

                Collection<PSObject> results = ps.Invoke();
                foreach (PSObject r in results)
                {
                    text.Dispatcher.Invoke(() =>
                    {
                        text.Text += r.ToString();
                    });
                    await Task.Delay(100);
                }                
            }
        }

也许我遗漏了一些重要的东西。请帮助我了解如何解决此问题。

qqcoboo 回答:使用异步和等待实时更新数据

不要使用同步调用并等待所有结果返回的 ps.Invoke(),而是使用 ps.BeginInvoke()。然后订阅输出 PSDataCollection 的 DataAdded 事件并使用该操作更新您的 ui。

private async void run_click(object sender,RoutedEventArgs e)
{
    Text1.Text = "";
    await Task.Run(() => PS_Execution(Text1));
}


internal async Task PS_Execution(TextBox text)
{
    using PowerShell ps = PowerShell.Create();
    ps.AddScript(script.ToString());

    PSDataCollection<string> input = null;
    PSDataCollection<string> output = new();
    IAsyncResult asyncResult = ps.BeginInvoke(input,output);

    output.DataAdded += (sender,args) =>
    {
        var data = sender as PSDataCollection<string>;
        text.Dispatcher.Invoke(() =>
        {
            text.Text += data[args.Index];
        });

    };
}

本文链接:https://www.f2er.com/3164.html

大家都在问