【问题标题】:Right usage of delegate and async methods正确使用委托和异步方法
【发布时间】:2017-11-10 10:20:12
【问题描述】:

所以一个简单的应用程序有一个按钮来从服务器获取数据,然后更新 UI 中的文本。 另外,我想启动另一个线程,每 3 秒再次获取数据。 下面的代码是创建线程和更新 UI(绑定值)的正确方法吗? 在这种情况下使用委托 NoArgDelegate 有缺点吗?或者在委托中传递异步方法是一个坏主意?我仍在尝试了解代表和调度程序的概念。

    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;
    }

【问题讨论】:

    标签: c# .net wpf delegates dispatcher


    【解决方案1】:

    你误解了BeginInvoke 的作用。它不会创建新线程。

    但是,无论如何您都不应该创建线程。对于循环重复的动作,请使用计时器。

    我推荐一个DispatcherTimer,带有一个异步Tick 事件处理程序:

    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());
    }
    

    【讨论】:

      猜你喜欢
      • 2010-11-27
      • 2011-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-25
      • 2017-06-23
      • 2022-11-08
      • 1970-01-01
      相关资源
      最近更新 更多