简体   繁体   English

使用System.Threading.Thread时WPF应用程序崩溃

[英]WPF application crashes when using System.Threading.Thread

I have a button named submit_Button which has the following code in the OnClicked event: 我有一个名为submit_Button的按钮,该按钮在OnClicked事件中具有以下代码:

    Thread thread = new Thread(new ThreadStart(heavyWork));
    thread.Start();

heavyWork function code : heavyWork功能代码:

private void heavyWork()
{
    DisableUI();

    string Name = Name_textBox.Text;
    celebrityName = Name.Replace(" ", "+");
    string queryURL = "http://stackoverflow.com";

    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(queryURL);
    request.Method = "GET";
    // make request for web page
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    StreamReader htmlSource = new StreamReader(response.GetResponseStream());

    string htmlStringSource = string.Empty;
    htmlStringSource = htmlSource.ReadToEnd();
    response.Close();

    //var regex = new Regex(@"<FONT class=""result"">(.*?)</FONT>");
    var regex = new Regex(@"<span class=""kno-a-v"">(.*?)</span>");
    var match = regex.Match(htmlStringSource);
    var result = match.Groups[1].Value;

    result = HttpUtility.HtmlDecode(result);
    MessageBox.Show(result);

    EnableUI();
}

// Functions
private void DisableUI()
{
    celebrityName_textBox.IsEnabled = false;
    submit_Button.IsEnabled = false;
    infoType_listBox.IsEnabled = false;
    preloader_Image.Visibility = Visibility.Visible;
}

private void EnableUI()
{
    celebrityName_textBox.IsEnabled = true;
    submit_Button.IsEnabled = true;
    infoType_listBox.IsEnabled = true;
    preloader_Image.Visibility = Visibility.Hidden;
}

When I run the application, then press the button, the application crashes immediately! 当我运行该应用程序时,然后按一下按钮,该应用程序立即崩溃!

What's happening ? 发生了什么 ? I tried to use BackgroundWorker Instead, but when I can worker.RunWorkerAsync() nothing happens ( the worker doesn't start ). 我尝试使用BackgroundWorker代替,但是当我可以使用worker.RunWorkerAsync()什么也没发生(工作器无法启动)。

DisableUI() is changing the state of UI controls on a thread which is not the UI thread. DisableUI()正在更改不是UI线程的线程上的UI控件的状态。 This is disallowed in WPF, because it is a single threaded UI framework , and only allows you to change controls on something called the UI thread. 在WPF中,这是不允许的,因为它是单线程UI框架 ,并且仅允许您更改UI线程上的控件。 Dispatcher.Invoke()/BeginInvoke() is your friend. Dispatcher.Invoke()/ BeginInvoke()是您的朋友。

Good MSDN article on using the Dispatcher 关于使用Dispatcher的MSDN优秀文章

You are going to want to do any UI related stuff on the UI thread, you can do this with the dispatcher, like so: 您将要在UI线程上执行任何与UI相关的工作,您可以使用调度程序执行此操作,如下所示:

private void heavyWork()
{
    Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(DisableUI));
    //rest of method
    Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(EnableUI));
}

When using Background Worker your code should look like something like this: Notice that when you start worker.RunWorkerAsync() method BackgroundWorkerDoWork is called 使用Background Worker时,代码应如下所示:请注意,当启动worker.RunWorkerAsync()方法时,将调用BackgroundWorkerDoWork

BackgroundWorker _backgroundWorker = new BackgroundWorker
{
   WorkerReportsProgress = true,
   WorkerSupportsCancellation = true
};
_backgroundWorker.DoWork += BackgroundWorkerDoWork;
_backgroundWorker.RunWorkerCompleted += BackgroundWorkerRunWorkerCompleted;

 void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
 {
     //DU STUFF HERE
 }

void BackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    /DO STUFF HERE LIKE HIDE / SHOW / ENABLE/ DISABLE buttons
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM