2014-03-25 2 views
1

은 내가 몇 초간의 지연을 필요 BackgroundThreadProc() 나는 방법WPF 스레드 지연

// get the dispatcher for the UI thread 
var uiDispatcher = Dispatcher.CurrentDispatcher; 
Task.Factory.StartNew(() => BackgroundThreadProc(uiDispatcher)); 

으로 새 작업에 전화하는 방법이있다. 나는 DispatcherTimer와 task.delay 함수로 시도했지만 작동하지 않았다. 작동 한 유일한 것은 System.Threading.Thread.Sleep(1) 이었지만 나는 Thread.Sleep() 기능이 최상의 솔루션이라고 생각하지 않습니다. 내가 알아 낸 것처럼 DispatcherTimer는 UI 스레드에서 실행되고 있기 때문

public void BackgroundThreadProc(Dispatcher uiDispatcher) 
{ 
    for (var i = 0; i < 100; i++) 
    { 
     var task = Task.Delay(1000).ContinueWith(t => 
     { 
      // create object 
      var animal = new Animal { Name = "test" + i }; 
      uiDispatcher.Invoke(new Action(() => log(animal))); 
     }); 
    } 
} 

가 작동하지 않았다 :

이 제 기능입니다. UI 스레드가 아닌 다른 스레드에있는 함수에서 지연을 어떻게 수행 할 수 있습니까?

업데이트 :

가 지금은 타이머에 그것을 시도 :

public void BackgroundThreadProc(Dispatcher uiDispatcher) 
    { 
     for (var i = 0; i < 100; i++) 
     { 
      var _delayTimer = new System.Timers.Timer(); 
      _delayTimer.Interval = 1000; 
      //_delayTimer.Enabled = true; 
      _delayTimer.Elapsed += delegate 
      { 
       var animal = new Animal { Name = "test" + i }; 
       uiDispatcher.Invoke(new Action(() => log(animal))); 
       _delayTimer.Stop(); 
      }; 
      _delayTimer.Start(); 
     } 
    } 

답변

4

사용 Task.Delay는 asynchrnoously 지연을 소개 : 당신은 C# 4.0로 제한

var task = Task.Delay(1000) 
    .ContinueWith(t => BackgroundThreadProc()); 
+0

Hy, ypur 대답에 감사드립니다. 귀하의 예제와 함께 시도했지만 문제가 지연 후 그것은 "test100"내 출력에 쓰기 때문에 지연 후 루프를 이미 finines 있지만 모든 후 i ++ 지연 싶습니다. 내 게시물에 BackgroundThreadProc() 추가했습니다. – user2644964

+0

@ user2644964 '타이머'만 원하는 것처럼 들립니다. TPL을 사용하여이 작업을 수행 할 수 있지만 그 이상의 가치가 있습니다. 그냥 '타이머'를 사용하십시오. – Servy

+0

Hy, 당신이 System.Timers.Timer를 의미하는 타이머가 있습니까? 나는 예제를 시도하고 "Update"아래에서 메인 포스트를 업데이트했다. 당신이 시도한 기능을 찾을 수있다. 나는 거기에 같은 문제가 결국 출력에만 houndret 시간 "test100"씁니다. – user2644964

1

있습니까? 나는 당신이 아니라고 생각한다. 왜냐하면 Task.Delay을 사용할 수 없기 때문이다.

그래서, BackgroundThreadProcasync 방법을 만들고 그 안에 await를 사용 : 당신은 정말 여기 Task.Factory.StartNew 필요하지 않습니다, 실행이 await Task.Delay 후 스레드 풀에 계속

// get the dispatcher for the UI thread 
var uiDispatcher = Dispatcher.CurrentDispatcher; 
var task = BackgroundThreadProc(uiDispatcher)); 

// ... 

public async Task BackgroundThreadProc(Dispatcher uiDispatcher) 
{ 
    for (var i = 0; i < 100; i++) 
    { 
     await Task.Delay(1000).ConfigureAwait(false); 

     // create object 
     var animal = new Animal { Name = "test" + i }; 
     uiDispatcher.Invoke(new Action(() => log(animal))); 
    } 
} 

.

분명히 UI를 업데이트하는 것은 BackgroundThreadProc입니다. 그런 경우, 단지 ConfigureAwait(false)를 제거하고 uiDispatcher.Invoke을 사용하지 마십시오

public async Task BackgroundThreadProc() 
{ 
    for (var i = 0; i < 100; i++) 
    { 
     await Task.Delay(1000); 

     // create object 
     var animal = new Animal { Name = "test" + i }; 
     log(animal); 
    } 
} 

를이 루프는 WPF UI 스레드에서 비동기 적으로 실행됩니다. 당신이Task.Delay 전에 다른 CPU 바인딩 작업 이있는 경우 (Unwrap주의)

그렇지 않으면, 당신은 UI를 동결 방지하기 위해 Task.Factory.StartNew이 필요할 수 있습니다

var task = Task.Factory.StartNew(() => 
    BackgroundThreadProc(uiDispatcher)).Unwrap(); 

또한 Task.Run을 사용할 수있는 자동으로 내부 작업을 풀어줍니다.

var task = Task.Run(() => BackgroundThreadProc(uiDispatcher));