C# 无法在启动线程之前更改WPF控件状态

C# 无法在启动线程之前更改WPF控件状态,c#,wpf,multithreading,C#,Wpf,Multithreading,我想在单击“开始”按钮后更改wpf控件的状态 这幅画正是我想要的 下面是我的代码 private bool _bWorking = false; public delegate void UpdateStatusDelegate(); private void SetStatus(bool bEnable) { if (bEnable) { tbName.IsReadOnly = false; barStatus.Visibility = Vi

我想在单击“开始”按钮后更改wpf控件的状态

这幅画正是我想要的

下面是我的代码

private bool _bWorking = false;
public delegate void UpdateStatusDelegate();

private void SetStatus(bool bEnable)
{
    if (bEnable)
    {
        tbName.IsReadOnly = false;
        barStatus.Visibility = Visibility.Hidden;
        btnStart.IsEnabled = true;
        btnStop.IsEnabled = false;
        btnClose.IsEnabled = true;
    }
    else
    {
        tbName.IsReadOnly = true;
        barStatus.Visibility = Visibility.Visible;
        btnStart.IsEnabled = false;
        btnStop.IsEnabled = true;
        btnClose.IsEnabled = false;
    }
}

internal void UpdateStatus()
{
   SetStatus(true);
   _bWorking = false;
}

private void ThreadFunc()
{
    //for (; ; )
    //{
    //    // do something here
    //    if (_bWorking == false)
    //        break;
    //}
    Thread.Sleep(500);
    this.Dispatcher.Invoke(new UpdateStatusDelegate(UpdateStatus));
}

private void btnStart_Click(object sender, RoutedEventArgs e)
{
    _bWorking = true;
    SetStatus(false);
    this.UpdateLayout();//this.InvalidateVisual();
    try
    {
        Thread t = new Thread(new ThreadStart(() =>
        {
            ThreadFunc();
        }));
        t.IsBackground = true;
        t.Name = "test status";
        t.Start();

        while (t.IsAlive)
        {
            // wait thread exit
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }        
}

private void btnStop_Click(object sender, RoutedEventArgs e)
{
    _bWorking = false;
    SetStatus(true);
}
但实际上,在我单击按钮开始后,UI似乎冻结,线程退出,UI变得正常

我的VS是VS2010

这个职位不适合我

编辑摘要:

将委托void UpdateStatusDelegate()和函数UpdateStatus()添加到我的代码中

//等待线程退出

后台线程的全部要点是不要通过阻塞UI线程来等待它。不要


相反,让线程在完成时通知您的UI。

尝试使用BackgroundWorker组件,它可能会对您有所帮助。有关更多信息,请查看可用代码

    public delegate void UpdateStatusDelegate();
    private bool _bWorking = false;

    private void SetStatus(bool bEnable)
    {
        if (bEnable)
        {
            tbName.IsReadOnly = false;
            barStatus.Visibility = Visibility.Hidden;
            btnStart.IsEnabled = true;
            btnStop.IsEnabled = false;
            btnClose.IsEnabled = true;
        }
        else
        {
            tbName.IsReadOnly = true;
            barStatus.Visibility = Visibility.Visible;
            btnStart.IsEnabled = false;
            btnStop.IsEnabled = true;
            btnClose.IsEnabled = false;
        }
    }

    internal void UpdateStatus()
    {
        SetStatus(true);
    }

    private void ThreadFunc()
    {
        try
        {
            // use Stopwatch to simulate jobs
            var watch = Stopwatch.StartNew();
            for (; ; )
            {
                var elapsedMs = watch.ElapsedMilliseconds;
                if (elapsedMs > 10000 // 10 seconds
                    || _bWorking == false)
                {
                    break;
                }
            }
            watch.Stop();
            this.Dispatcher.Invoke(new UpdateStatusDelegate(UpdateStatus));
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        _bWorking = false;
    }

    private void btnStart_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            _bWorking = true;
            SetStatus(false);
            Thread t = new Thread(new ThreadStart(() =>
            {
                ThreadFunc();
            }));
            t.IsBackground = true;
            t.Name = "test status";
            t.Start();
            //while (t.IsAlive)
            {
                // wait thread exit
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    private void btnStop_Click(object sender, RoutedEventArgs e)
    {
        _bWorking = false;
        SetStatus(true);
    }

但您希望在线程完成后更改UI。如果您等待线程,则不需要线程,您可以在不使用第二个线程的情况下执行此操作。你不想等待,你想让你的线程通知你的UI什么时候可以做那些你想在线程完成后做的事情。我添加了delegate void UpdateStatusDelegate()和函数UpdateStatus()。它仍然不起作用。@Rock您仍然有繁忙的等待循环。停止等待线程。我仍然无法单击停止按钮。我使用秒表模拟作业。现在可以了。谢谢。可能是重复的谢谢,但它对我不起作用。那篇文章谈到了WinForm,我的问题是WPF。