正确使用委托和异步方法
Right usage of delegate and async methods
一个简单的应用程序,它有一个从服务器获取数据的按钮,然后更新 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;
}
您误解了 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());
}
一个简单的应用程序,它有一个从服务器获取数据的按钮,然后更新 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;
}
您误解了 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());
}