2013-08-08 2 views
2

У меня есть кнопка с именем submit_Button, который имеет следующий код в OnClicked событие:WPF сбой приложения при использовании System.Threading.Thread

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

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; 
} 

Когда я запускаю приложение, нажмите кнопку, приложение немедленно сработает!

Что происходит? Я пытался использовать BackgroundWorker Вместо этого, но когда я могу worker.RunWorkerAsync() ничего не происходит (рабочий не запускается).

+0

Какое исключение вы получаете? –

+4

Во-первых, вы делаете материал пользовательского интерфейса в потоке, который не имеет элементов интерфейса. Возможно, вы захотите заглянуть в 'Dispatcher.Invoke'. Это даже начало «тяжелой работы»? Если это так, какая строка сбрасывает его? – Artless

+2

, если вы закомментируете 'DisableUI()' и 'EnableUI()' все еще сбой? – Damith

ответ

2

Вы будете хотеть, чтобы делать какой-либо интерфейс связанные вещи в потоке пользовательского интерфейса, вы можете сделать это с диспетчером, например, так:

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

Большое вам спасибо, это сработало отлично. Я должен привыкнуть писать 'Dispatcher.Invoke()'. –

2

DisableUI() изменяет состояние элементов управления пользовательского интерфейса в потоке, который не является потоком пользовательского интерфейса. Это запрещено в WPF, потому что это single threaded UI framework и позволяет изменять элементы управления только на том, что называется потоком пользовательского интерфейса. Dispatcher.Invoke()/BeginInvoke() - ваш друг.

Good MSDN article on using the Dispatcher

+0

Как насчет того, чтобы предоставить источник для просмотра? –

1

При использовании фона Рабочего код должен выглядеть как-то вроде этого: Обратите внимание, что при запуске 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 
} 
Смежные вопросы