我向Github Api请求所以我有异步方法,这些都可以完成这项工作。在它之前,我总是在方法中调用它们,从命令调用(实际上是DelegateCommand)。但现在我想在ViewModel中做请求,因为我需要在页面上显示列表。我正在使用Prism来连接视图和视图模型。 因为我无法使viewmodel异步,所以我无法使用await字,所以我尝试做一些像从task或task.wait获取结果的东西。但有了这个,我有同样的结果。我的应用程序停止在请求时使用白色显示。我读了一些关于它的信息,我理解在非异步方法中调用异步方法很糟糕,它会导致死锁,但我不知道如何处理这个问题。而且我认为死锁导致应用程序停止工作。 这是app死的方法:
public async Task<IEnumerable<RepositoryModel>> GetRepositoriesAsync()
{
try
{
var reposRequest = new RepositoryRequest { Sort = RepositorySort.FullName };
var gitHubRepos = await _gitHubClient.Repository.GetAllForCurrent(reposRequest); //async request, don't say about name convention, it is not my method.
var gitRemoteRepos = new List<RepositoryModel>();
foreach ( var repository in gitHubRepos )
{
var repos = new RepositoryModel();
repos.RepositoryTypeIcon = GetRepositoryTypeIcon(repository);
gitRemoteRepos.Add(repos);
}
return gitRemoteRepos;
}
catch ( WebException ex )
{
throw new Exception("Something wrong with internet connection, try to On Internet " + ex.Message);
}
catch ( Exception ex )
{
throw new Exception("Getting repos from github failed! " + ex.Message);
}
}
这是viewmodel:
public class RepositoriesPageViewModel : BindableBase
{
private INavigationService _navigationService;
private readonly Session _session;
public ObservableCollection<RepositoryModel> Repositories { get; }
private readonly RepositoriesManager _repositoriesManager;
public RepositoriesPageViewModel(INavigationService navigationService, ISecuredDataProvider securedDataProvider)
{
_navigationService = navigationService;
var token = securedDataProvider.Retreive(ConstantsService.ProviderName, UserManager.GetLastUser());
_session = new Session(UserManager.GetLastUser(), token.Properties.First().Value);
var navigationParameters = new NavigationParameters { { "Session", _session } };
_repositoriesManager = new RepositoriesManager(_session);
var task = _repositoriesManager.GetRepositoriesAsync();
//task.Wait();
Repositories = task.Result as ObservableCollection<RepositoryModel>;
}
}
答案 0 :(得分:3)
我建议使用我的NotifyTask<T>
type,它提供Task<T>
周围的数据绑定包装。我在article on async MVVM data binding中更完整地解释了这种模式。
public class RepositoriesPageViewModel : BindableBase
{
private INavigationService _navigationService;
private readonly Session _session;
public NotifyTask<ObservableCollection<RepositoryModel>> Repositories { get; }
private readonly RepositoriesManager _repositoriesManager;
public RepositoriesPageViewModel(INavigationService navigationService, ISecuredDataProvider securedDataProvider)
{
_navigationService = navigationService;
var token = securedDataProvider.Retreive(ConstantsService.ProviderName, UserManager.GetLastUser());
_session = new Session(UserManager.GetLastUser(), token.Properties.First().Value);
var navigationParameters = new NavigationParameters { { "Session", _session } };
_repositoriesManager = new RepositoriesManager(_session);
Repositories = NotifyTask.Create(GetRepositoriesAsync());
}
}
private async Task<ObservableCollection<RepositoryModel>> GetRepositoriesAsync()
{
return new ObservableCollection<RepositoryModel>(await _repositoriesManager.GetRepositoriesAsync());
}
请注意,使用此方法,您的数据绑定将使用Repositories.Result
来访问实际的集合。其他属性也可用,最值得注意的是Repositories.IsCompleted
和Respositories.IsNotCompleted
,用于显示/隐藏繁忙的微调器。