2013-11-15 2 views
2

나는이 질문이 전에 100 번 요청되었지만 내가 읽은 모든 대답은 나를 위해 일하지 않았다는 것을 안다. 그래서 나는 내 운을 시험해보고 다시 물어 보겠습니다.다른 스레드에서 ProgressBar 업데이트

ValueChanged 이벤트에서 메서드를 호출하는 SliderBar이 있습니다. 이 방법에서는 시간이 걸리는 작업을 수행합니다.이 시간에는 사용자가 "근무중인"ProgressBar (IsIndeterminate=true)을 보길 원합니다.

모든 메서드 루프가 완료 될 때까지 ProgressBar이 (UI에서) 작동하도록 성공하지 못했습니다. 스레드를 시도했습니다 : BackgroundWorkerasync 작업이 성공했지만 성공하지 못했습니다.

무엇이 잘못 되었나요?

은 방법 :

private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e){ 
     WorkingBar.IsIndeterminate = true;  //change the progressBar   
     SqlAThread = new Thread(SqlAStart);  
     SqlAThread.Start(); 
    } 

스레드 :

private void SqlAStart() 
    { 
     ... //do some stuff 
    } 
+0

doWork 메소드의 디스패처 구문은 사용하고자하는 것입니다. UI 코드를 UI 스레드에 삽입하여 원하는 작업을 UI 스레드에 푸시하고자 할 때, 여기에서하는 것처럼 보이게됩니다. 진행률 막대의 속성을 변경하려면이 구문을 사용하여 진행률 막대도 업데이트하십시오. – JMK

+0

@JMK이 프로 파티는 내가 바꾸고 싶은 것입니다.이 proprty가 "true"일 때 progressBar는 "작동"모드로되어 있습니다 (제 생각에는 ...?). 실제로, 모든 루프가 완료되었을 때만 작동합니다. =/ – Yaron

답변

3

당신은 많은 시간이 소요 SqlAStart() 방법을 실행하기 위해 새로운 트레드를 시작하지만 SqlAStart 즉시 작업 (Dispatcher.Invoke()를 통해) UI 스레드에 다시를 푸시합니다. 따라서 UI가 중단되고 작업이 완료 될 때까지 진행률이 표시되지 않습니다. IProgress<T> 사용이 매우 간단합니다

private void SqlAStart() 
{ 
    ServerThread = new Thread(HttpSrv.listen); 
    ServerThread.Start(); 
    ... 

    this.Dispatcher.Invoke((Action)(() => { 
     WorkingBar.Value = ...     
    })); 

    .... 
} 
+0

이 너무 작동합니다. – Marc

+0

@Sphinxxx 감사합니다! – Yaron

0

전체 긴 과정을 입력하는 대신, 나는 Progress Bar update from Background worker stalling에 대한 내 대답을 살펴보고 여러분을 초대 것 여기 StackOverflow에 질문. BackgroundWorker 개체를 올바르게 사용하여 ProgressBar의 진행률 값을 업데이트하는 방법을 보여줍니다.

자세한 내용은 MSDN의 BackgroundWorker Class 페이지를 참조하십시오. Slider_ValueChanged에서

+0

안녕하세요 @ sheridan 코드를 사용해 보았습니다. (실제로는 첫 시도였습니다) 예제를 이해하지만 코드에서 사용하지 마십시오. .. – Yaron

+0

@ Yaron, 지금은 코드를 무시하십시오. 이 예제 코드를 새 WPF 응용 프로그램이나 프로젝트에 넣고 작동 시키십시오. * 그런 다음 * 실험 할 예제가 있으면 코드에 적용 할 수 있어야합니다. – Sheridan

+0

나는 그것을 시도했고 새로운 프로젝트에서 일했다. 하지만 지금은 내 코드에서 그것을하려고 할 때 그것은 나를 위해 일을 dosnt – Yaron

1

: SqlAStart에서

만하면 진행률 표시 줄을 업데이트 할 필요가 Dispatcher.Invoke()은 어떻게 당신이 (거의)를 사용해서는 안

private async void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) 
{ 
    if (State.Value > 0) 
    { 
    var progress = new Progress<int?>(value => 
    { 
     WorkingBar.IsIndeterminate = (value == null); 
     if (value != null) 
     WorkingBar.Value = value.Value; 
    }); 
    await Task.Run(() => doWork(progress)); 
    Task.Run(SqlAStart); 
    } 
    ... 
} 

private void SqlAStart(IProgress<int?> progress) 
{ 
    ServerTask = Task.Run(HttpSrv.listen); 
    ... 
} 

private void doWork(IProgress<int?> progress) 
{ 
    if (progress != null) 
    progress.Report(null); 
    ... 
} 

Dispatcher, Thread 또는 BackgroundWorker입니다.

+0

안녕하세요 @Stephen Cleary, 나는 (도덕적으로 IProgress 을 알고 있었지만 btw, 고마워.)하지만 여전히, SqlAstart 완료 직후의 UI 업데이트. – Yaron

+0

@ Yaron 방법은 무엇입니까? UI 스레드를 호출하고 잠시 동안 블로킹하면 분명히 진행중인 동안 다른 스레드는 업데이트 할 수 없습니다. – Servy

관련 문제