2017-02-28 2 views
-1

다중 스택 오버 플로우, codeproject 솔루션을 읽으면 문제가 발생할 수 있습니다.wpf 타이머 응용 프로그램을위한 다중 디스패치 타이머 : 여러 타이머를 동시에 실행

창에로드 된 usercontrol에 DataGrid가 있어야합니다. DataGrid의 각 DataRow는 타이머 설정을 나타냅니다.

처럼 :

timer name : Test 1 , Timer : 1h 3m 
timer name : Test 2 , Timer : 2h 2m 
timer name : Test 3 , Timer : 3h 1m 

버튼 시작을 클릭 행을 선택하면, 해당 행의 타이머를 시작합니다. 그리고 디스패처 틱 이벤트를 통해이 작업을 완료했습니다. 이제는 같은 시간에 같은 일을 할 또 다른 (또는 두 개 또는 ...) 타이머를 시작해야합니다. 나는 이것에 붙어있다. 내가 시도한 것을 나에게 나누게 해줘! MainWindow.xaml.cs를

if (btnStart.Content.ToString() == "Start") 
     { 
      if (_AUC == ActiveUserControl.Grid) 
      { 
       runningRow = (TaskGridData)_TG.dgEmployee.SelectedItem; 
       if (runningRow != null) 
       { 
        currentlyRunningID.Add(runningRow.ID); 
        btnStart.Content = "Stop"; 
        //worker.RunWorkerAsync(runningRow); 
        StartTimer(runningRow); 
       } 
      } 
     } 
     else if (btnStart.Content.ToString() == "Stop") 
     { 
      btnStart.Content = "Start"; 
      StopTimer(); 

     } 
private DateTime TimerStart { get; set; } 
    private void StartTimer(TaskGridData tgd) 
    { 
     dispatcherTimer = new DispatcherTimer(); 

     dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 1, 0); 
     dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick); 
     TimerStart = DateTime.Now; 
     dispatcherTimer.Start(); 
     //worker.RunWorkerAsync(); 

     //string etime = DateTime.Now.Second.ToString(); 
    } 

    private void StopTimer() 
    { 
     dispatcherTimer.Stop(); 
    } 
private void dispatcherTimer_Tick(object sender, EventArgs e) 
    { 
     var currentValue = DateTime.Now - TimerStart; 
     runningRow.Duration = DurationValueToString(currentValue); 
     temp = (List<TaskGridData>)_TG.dgEmployee.ItemsSource; 
     foreach (TaskGridData item in temp) 
     { 
      if (item.ID == runningRow.ID) 
      { 
       item.Duration = DurationValueToString(DurationStringToVlaue(item.Duration) - DurationStringToVlaue(runningRow.Duration)); 
       break; 
      } 
     } 
     //_TG.dgEmployee.ItemsSource = null; 
     //_TG.dgEmployee.ItemsSource = temp; 
     Thread NewThreadforStartProcessAfterTraining = new Thread(() => UpdateGrid()); 
     NewThreadforStartProcessAfterTraining.IsBackground = true; 
     NewThreadforStartProcessAfterTraining.SetApartmentState(ApartmentState.STA); 
     NewThreadforStartProcessAfterTraining.Start(); 

    } 
    private void UpdateGrid() 
    { 
     this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => 
     { 
      _TG.dgEmployee.ItemsSource = null; 
      _TG.dgEmployee.ItemsSource = temp; 
     })); 

    } 

에서

btnStartClickEvent은이 코드는 하나의 타이머 알고있다. 두 번째 행을 클릭하고 타이머를 시작하려고하면 틱 이벤트에 오류가 발생합니다. running row은 null입니다.

이 코드를 유지하고 여러 타이머에서 어떻게 작동시키는 지 궁금합니다. 멀티 스레딩 일 수 있습니다. 가이드가 도움이 될 것입니다.

답변

0
Thread NewThreadforStartProcessAfterTraining = new Thread(() => UpdateGrid()); 
    NewThreadforStartProcessAfterTraining.IsBackground = true; 
    NewThreadforStartProcessAfterTraining.SetApartmentState(ApartmentState.STA); 
    NewThreadforStartProcessAfterTraining.Start(); 

이렇게하면 시각적 트리를 업데이트 할 수 없기 때문에 새로운 STA 스레드를 시작하는 모든 부분이 불필요하고 잘못되었습니다. 이전 대답 중 하나에서 STA 스레드를 사용하는 올바른 예를 찾을 수 있습니다. https://stackoverflow.com/a/42473167/6996876

WPF에서 스레드 유사성의 개념을 이해하려고합니다.

UI 작업을 운영자에게 위임해야하는 UpdateGrid()이 있으면됩니다.

또한, Tick 이벤트에 인수를 전달 여기에 이미 설명 : https://stackoverflow.com/a/16380663/6996876 를 귀하의 경우에는 당신이 그것을 대신 이벤트에 전달있어 너무 현재의 독특한 runningRow을 변경할 수 있습니다.

+0

backgroundworker_dowork 이벤트에 내'UpgradeGrid()'메소드를 추가하려고했습니다. 백그라운드에서 DataGrid를 업그레이드하십시오. 그러나 나는 그 방법을 시도하는 동안 그것은 갱신 할 수 없게된다. –

+0

* dispatcher *에 모든 UI 작업 *이 없습니다. 내 대답을 잘 읽으십시오. –