잠 UI

2014-07-22 3 views
1
을 일시 중지하지 않고 실행은

나는 텍스트 상자 2 초 기다렸다가 업데이트하려면이 간단한 프로그램을 작성했습니다잠 UI

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 

namespace WpfApplication1 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, RoutedEventArgs e) 
     { 
      for (int i = 0; i < 10; i++) 
      { 
       doSomething(i); 
      } 
     } 
     public void doSomething(int i) 
     { 
      System.Threading.Thread.Sleep(2000); 
      textBox1.Text += "this is the " + i + "th line\n"; 
     } 
    } 
} 

을하지만 난 그것을 실행할 때 UI 일시 정지 나는 UI와 아무것도 할 수 없습니다 . 그것은 동적이 아니며 textbox1에 표시되어야하는 모든 텍스트는 실행이 끝날 때 표시됩니다.

대신 System.Threading.Thread.Sleep 대신 사용할 수있는 대안이 있습니까?

+2

는 다른 스레드 수면을 가지고 있고,이 액션을 수행 할 때. – gunr2171

+2

타이머 사용. 절대로 주 스레드에서 절전(). –

답변

4

UI 스레드를 차단하지 않고 async/await을 사용할 수 있습니다.

for (int i = 0; i < 10; i++) 
{ 
    await doSomething(i); 
} 


public async Task doSomething(int i) 
{ 
    await Task.Delay(2000); 
    this.Text += "this is the " + i + "th line\n"; 
} 
+0

재미 있고, 동일한 것을 썼습니다. –

+0

내 프로그램이 비동기 및 작업을 키워드로 알지 못합니다. 일부 라이브러리 또는 참조를 사용해야합니까? (넷을 사용하고 있습니다.) – abdolahS

+1

@abdolahS - 'async/await' 귀하의 프로젝트에 .Net 4.5 타겟 프레임 워크 이상을 사용해야합니다. –

3

문제는 UI 스레드에 자고있다. 따라서 UI는 당신이 잠들 때까지 업데이트되지 않습니다.

이상적인 시나리오는 UI 스레드에서 잠자기 대신 DispatcherTimer을 사용하는 것입니다.

private void button1_Click(object sender, RoutedEventArgs args) 
{ 
    int i = 0; 
    DispatcherTimer timer = new DispatcherTimer(); 
    timer.Interval = TimeSpan.FromSeconds(2); 
    timer.Tick += (s, e) => 
    { 
     if (i == 10) 
     { 
      timer.Stop(); 
     } 
     else 
     { 
      textBox1.Text += "this is the " + i + "th line\n"; 
      ++i; 
     } 
    }; 
    timer.Start(); 
} 

- 당신은 UI 발송자의 코드를 위임해야 업데이트 할 UI에 대한 있도록 타이머가 배경 스레드에서의 경과 이벤트 핸들러를 실행하기 때문에 여기 대신 Timer 클래스의 DispatcherTimer를 제안하고있다. 하지만 DispatcherTimer는 UI 스레드 자체에서 Tick 이벤트 핸들러를 실행하므로 UI ​​디스패처에서 다시 마샬링 할 필요가 없습니다.

1

간단한 방법 :

private void button1_Click(object sender, RoutedEventArgs e) 
{ 
    DoSomethingAsync(); 
} 

private async void DoSomethingAsync() 
{ 
    for (int i = 0; i < 10; i++) 
    { 
     await doSomething(i); 
    } 
} 

async Task doSomething(int i) 
{ 
    await Task.Delay(1000); 
    textBox1.Text += "this is the " + i + "th line\n"; 
}