我的viewmodel中有一个看起来像这样的任务:
ICommand getWeather;
public ICommand GetWeatherCommand =>
getWeather ??
(getWeather = new Command(async () => await ExecuteGetWeatherCommand()));
public async Task ExecuteGetWeatherCommand()
{
if (IsBusy)
return;
IsBusy = true;
try
{
WeatherRoot weatherRoot = null;
var units = IsImperial ? Units.Imperial : Units.Metric;
if (UseGPS)
{
//Get weather by GPS
var local = await CrossGeolocator.Current.GetPositionAsync(10000);
weatherRoot = await WeatherService.GetWeather(local.Latitude, local.Longitude, units);
}
else
{
//Get weather by city
weatherRoot = await WeatherService.GetWeather(Location.Trim(), units);
}
//Get forecast based on cityId
Forecast = await WeatherService.GetForecast(weatherRoot.CityId, units);
var unit = IsImperial ? "F" : "C";
Temp = $"Temp: {weatherRoot?.MainWeather?.Temperature ?? 0}°{unit}";
Condition = $"{weatherRoot.Name}: {weatherRoot?.Weather?[0]?.Description ?? string.Empty}";
}
catch (Exception ex)
{
Temp = "Unable to get Weather";
//Xamarin.Insights.Report(ex);
}
finally
{
IsBusy = false;
}
}
如何才能到达该任务并使其正确执行该功能? 我的目标是在用户进入内容页面(StartPage)时立即执行。现在我使用下面的代码,但命令不会执行。
public StartPage ()
{
InitializeComponent ();
loadCommand ();
}
async Task loadCommand ()
{
var thep = new WeatherViewModel ();
await thep.ExecuteGetWeatherCommand ();
}
我将命令绑定到listview:
RefreshCommand="{Binding GetWeatherCommand}"
使用我当前的代码,Task不会执行。我错过了什么?
答案 0 :(得分:0)
首先,你的命名约定是奇怪的,theTask不是一个Task,所以你可能不应该把它称为一个。其次,因为您在构造函数中调用loadCommand而不是等待它,所以构造函数可以在函数完成之前完成。通常,您希望避免构造函数中的异步。
Stephen Cleary在这里有一篇关于构造函数异步的文章:http://blog.stephencleary.com/2013/01/async-oop-2-constructors.html
将处理程序附加到页面的Appearing事件并在那里执行异步工作可能是合适的。如果没有更多的上下文,有点难以说这是否是您用例的最佳方法。
例如:
public StartPage ()
{
InitializeComponent ();
Appearing += async (sender, args) => await loadCommand();
}
async Task loadCommand ()
{
var viewModel = new StartPageViewModel();
await viewModel.ExecuteCommand();
}