2011-01-27 2 views
0

backgound에서 많은 작업을 수행하는 wpf 응용 프로그램을 만들고 있지만 여전히 UI가 반응 적이어야하고 다양한 백그라운드 작업의 상태를 표시해야합니다. 또한 UI를 전혀 표시하지 않을 수도 있습니다.이 경우 주 양식의 인스턴스를 전혀 작성하지 않고 상태 메시지를 버려야합니다. 내가 시도했습니다 무엇백그라운드 스레드의 정보로 WPF 창을 업데이트하는 방법은 무엇입니까?

는 App.xaml에서

StartupUri="MainWindow.xaml"

을 제거하는 것입니다. 그런 다음 App.xaml.cs를, 나는이 필요한 경우, 기본 양식을 보여 주며, 모든 백그라운드 프로세스를 시작

`

public App() 
    { 
     Startup += new StartupEventHandler(App_Startup); 
    } 

    void App_Startup(object sender, StartupEventArgs e) 
    { 
     // Code which loads application settings is here 

     if (pf.ShowUI) 
     { 
      MainWindow mainWindow = new MainWindow(); 
      mainWindow.Show(); 
     } 

     // The background processes will begin here. 

    }` 

있습니다. 이 부분은 작동합니다.

은 UI의 배경에서 메시지를 전송하기 위해, 나는 아주 기본적인 메신저 구현했습니다 :

`

internal interface IMessageHandler 
{ 
    void ReceiveMessage(string message); 
} 

internal class Messenger 
{ 
    private static List<IMessageHandler> _handlers; 

    internal static void AddHandler(IMessageHandler handler) 
    { 
     _handlers.Add(handler); 
    } 

    internal static void RemoveHandler(IMessageHandler handler) 
    { 
     try 
     { 
      _handlers.Remove(handler); 
     } 
     catch (Exception ex) {} 
    } 

    internal static void Broadcast (string message) 
    { 
     foreach (IMessageHandler handler in _handlers) 
     { 
      handler.ReceiveMessage(message); 
     } 
    } 
}` 

주요 형태는 IMessageHandler 인터페이스를 구현을, 그리고 자신을 추가 Messenger를 시작할 때 처리기로 사용합니다. 주 양식으로 상태를 전송해야하는 모든 프로세스는 메신저의 Broadcast 메 시지를 호출하면됩니다.

내가 겪고있는 문제는 백그라운드 프로세스가 완료 될 때까지 메시지가 양식에 표시되지 않고 그때까지 UI가 잠겨 있다는 것입니다. 왜 내 백그라운드 프로세스 내 UI를 동결하는

`

public void ReceiveMessage(string message) 
    { 
     Dispatcher.Invoke(DispatcherPriority.Normal, 
       new Action<string>(AddText), 
       message); 
    } 

    private void AddText(string text) 
    { 

     Label myLabel = new Label(); 
     myLabel.Content = text; 
     stackPanel1.Children.Add(myLabel); 
     if (stackPanel1.Children.Count > 5) 
     { 
      stackPanel1.Children.RemoveAt(0); 
     } 
    }` 

다음과 같이

수신 메시지를 처리하는 UI의 코드는 무엇입니까? 그것을 막기 위해 무엇을 할 수 있습니까? 그리고 내 UI가 상태 메시지로 업데이트되지 않는 이유는 무엇입니까?

+0

패턴을 MVVM으로 사용하여 뷰를 모델 데이터에 바인딩하는 것이 좋습니다. – HyLian

답변

1

나는 똑같은 문제가있어서 this blog post가 해결하는데 도움이되었습니다.

+0

내가해야 할 일은 백그라운드 스레드를 새로운 스레드로 명시 적으로 시작하는 것입니다. 나는 그들이 App_Startup 메서드의 끝에서 UI에 대한 별도의 스레드에 있다는 것을 호출함으로써이를 가정했습니다. 이것은 사실이 아닌 것처럼 보입니다. 새 스레드에서 프로세스를 시작하자마자 다른 모든 파트는 예상대로 정확하게 작동했습니다. 링크를 가져 주셔서 감사합니다. – RichieACC

+0

감사합니다. 행복하게 문제를 해결했습니다. – Asha

0

아마이 문제입니다 :

Dispatcher.Invoke(DispatcherPriority.Normal, 
       new Action<string>(AddText), 
       message); 

가로 변경 시도,

Dispatcher.BeginInvoke(DispatcherPriority.Normal, 
       new Action<string>(AddText), 
       message); 

Invoke를 사용하는 경우,이 방법이 실행됩니다 때문에 응용 프로그램 대기가 함께 완료,하지만하기 BeginInvoke 메서드가 비동기 적으로 호출되고 BeginInvoke에 참조 된 메서드가 실행되는 동안 응용 프로그램이 계속 실행됩니다.

이 읽기 ​​: whether to use Invoke or BeginInvoke

+0

Invoke와 BeginInvoke 사이를 스와핑해도 응용 프로그램에서 눈에 띄는 차이가 발생하지 않습니다. – RichieACC

0

은 UI를 동결 방지하기 위해 아래의 코드를 사용합니다. 내 응용 프로그램에서는 BackgroundWorker 클래스를 사용했습니다. 코드를 사용하여 폼의 내용을 변경하면 런타임 오류가 발생합니다.

나는 이것을 피하기 위해 아래 코드를 사용하고 있으며 완벽하게 작동합니다.

Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate() 
{ 
    rtf_status.AppendText("Validating XML against schema...Please wait\n"); 
})); 

참고 중괄호 사이의 뒷부분 ('{}') 양식에 뭔가를 변경하고자하는 경우 코드를 배치해야 곳이다.

+0

기본적으로이 코드는 내 것과 다르지 않습니다. 이름이 지정된 메소드를 사용하고있는 곳의 익명 메소드를 사용하고 있습니다. – RichieACC

관련 문제