2017-11-10 1 views
-1

서버에서 데이터를 가져 오는 버튼이 있고 UI의 텍스트를 업데이트하는 간단한 애플리케이션입니다. 또한 3 초마다 데이터를 다시 얻는 다른 스레드를 시작하려고합니다. 아래 코드는 스레드를 만들고 UI (바인딩 값)를 업데이트하는 올바른 방법입니까? 이 시나리오에서는 대리인 NoArgDelegate 단점을 사용합니까? 또는 대리자에서 비동기 메서드를 전달하는 것은 좋지 않은 생각입니까? 나는 여전히 대의원과 Dispatcher의 개념을 얻으려고 노력하고있다.델리게이트 및 비동기 메소드의 올바른 사용

private delegate void NoArgDelegate(); 
    public IAsyncCommand GetDataCommand { get; private set; } // binding for a "Get data" button 

    public JustAViewModel() 
    { 
     // ... 
     GetDataCommand = AsyncCommand.Create(() => GetDataAsync()); 

     var fetcher = new NoArgDelegate(ContinuouslyFetchData); 
     fetcher.BeginInvoke(null, null); 
    } 

    public string Value // in xaml: TextValue="{Binding Value}" 
    { 
     get => _value; 
     set 
     { 
      if (_value != value) 
      { 
       _value = value; 
       RaisePropertyChanged("Value"); 
      } 
     } 
    } 

    private async void ContinuouslyFetchData() 
    { 
     while (true) 
     { 
      System.Threading.Thread.Sleep(3000); 
      await GetDataAsync(); 
     } 
    } 

    private async Task<string> GetDataAsync() 
    { 
     Value = await Task.Run(() => DataProvider.GetData()); 
     return Value; 
    } 

답변

1

BeginInvoke의 오해입니다. 새 스레드를 만들지 않습니다.

그러나 어쨌든 스레드를 생성해서는 안됩니다. 주기적으로 반복되는 작업의 경우 타이머를 사용하십시오.

내가 비동기 Tick 이벤트 핸들러와 더불어, DispatcherTimer을 권하고 싶습니다 :

private readonly DispatcherTimer timer; 

public JustAViewModel() 
{ 
    timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(3) }; 
    timer.Tick += TimerTick; 
    timer.Start(); 
} 

private async void TimerTick(object sender, EventArgs e) 
{ 
    Value = await Task.Run(() => DataProvider.GetData()); 
}