循环中的WPF应用程序,如何不冻结整个应用程序?

Pat*_*ins 2 .net c# wpf multithreading

我正在玩WPF并遇到了问题.我用谷歌搜索,发现这个网站有我同样的问题,但没有任何有效的解决方案.

问题是我有一个按钮,可以处理一些数据(大约30秒).我想让按钮禁用并在文本框中写日志...问题是它没有禁用,并且在完成处理之前它没有在文本框上写任何东西.

任何的想法?

 private void button1_Click(object sender, RoutedEventArgs e)
 {
        this.button1.IsEnabled = false;
        //Long stuff here
         txtLog.AppendText(Environment.NewLine + "Blabla");
        //End long stuff here
        this.button1.IsEnabled = true;
 }
Run Code Online (Sandbox Code Playgroud)

Rob*_*nee 8

正如其他人所说的那样,使用这种BackgroundWorker或其他方法同时进行工作.

你可以在你的下面声明它Window,在Loaded事件的某个地方初始化它,并在Click事件中使用它.这是你的方法,修改后使用BackgroundWorker,假设你已经在Windowas 下声明了它_bw:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    _bw = new BackgroundWorker();
    _bw.DoWork += new DoWorkEventHandler((o, args) =>
    {
        //Long stuff here       
        this.Dispatcher.Invoke((Action)(() => txtLog.AppendText(Environment.NewLine + "Blabla")));
    });

    _bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler((o, args) =>
    {
        //End long stuff here
        this.Dispatcher.Invoke((Action)(() => this.button1.IsEnabled = true));
    });
}

private void button1_Click(object sender, RoutedEventArgs e)
{
    this.button1.IsEnabled = false;

    _bw.RunWorkerAsync();
}
Run Code Online (Sandbox Code Playgroud)

请注意,从另一个线程修改UI的任何内容都必须在一个Dispatcher.InvokeDispatcher.BeginInvoke调用中完成,WPF不允许您DependencyProperty从任何线程获取或设置值,而是创建对象的那个(更多关于此处).

如果你想读取txtLog而不是修改它,代码将是相同的:

//Long stuff here       
this.Dispatcher.Invoke((Action)(() => 
{
    string myLogText = txtLog.Text;
    myLogText = myLogText + Environment.NewLine + "Blabla";
    txtLog.Text = myLogText;
}));
Run Code Online (Sandbox Code Playgroud)