Ayb*_*ybe 6 .net c# data-binding wpf asynchronous
您能否判断以下代码段是否正确绑定到异步数据源?
虽然它似乎工作,即:UI不冻结,我不完全确定正确性,因为MSDN文档并没有真正谈论绑定到这些文档中的"异步"方法:
ObjectDataProvider.IsAsynchronous
<pages:HottestPageProxy x:Key="PageProxy" ></pages:HottestPageProxy>
<ObjectDataProvider x:Key="DataProviderArtists" IsAsynchronous="True" ObjectInstance="{StaticResource PageProxy}" MethodName="GetArtists">
<ObjectDataProvider.MethodParameters>
<system:String>Grabbing artists !</system:String>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
Run Code Online (Sandbox Code Playgroud)
(HottestPageProxy对象是一个为控件提供数据的小助手)
public class HottestPageProxy
{
[UsedImplicitly]
public async Task<ArtistsQuery> GetArtists([CallerMemberName] string memberName = "")
{
Console.WriteLine(memberName);
string apiKey = App.GetApiKey();
Task<ArtistsQuery> topHottt = Queries.ArtistTopHottt(new ArtistTopHotttParameters
{
ApiKey = apiKey,
Results = 100,
Buckets = new[] {ArtistTopHotttBuckets.Hotttnesss}
});
return (await topHottt);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:'等待topHottt'调用的方法
public static async Task<ArtistsQuery> ArtistTopHottt(ArtistTopHotttParameters parameters)
{
if (parameters == null) throw new ArgumentNullException("parameters");
return await Get<ArtistsQuery>(parameters);
}
private static async Task<T> Get<T>(Parameters parameters) where T : Query
{
if (parameters == null) throw new ArgumentNullException("parameters");
ValidateParameters(parameters);
string url = parameters.GetQueryUrl();
var value = new Uri(url);
using (var client = GetHttpClient())
using (var message = await client.GetAsync(url))
{
// fetch message content (removed)
return GetQueryResultObject<T>(s);
}
}
private static T GetQueryResultObject<T>(string json) where T : class
{
// create T from Json string (removed)
return t;
}
Run Code Online (Sandbox Code Playgroud)
使用AsyncEx编辑
使用您的库虽然现在的语法是:
<ItemsControl x:Name="ItemsControlTopHott"
ItemsSource="{Binding ... Path=Artists.Result.Artists ...}">
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
'Artists.Result.Artists'真的是你期望我用的吗?:)
新的语法使其更加混乱,因为源是:
public sealed class ArtistsQuery : Query
{
public List<Artist> Artists { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
没什么大不了的,但如果我能避免这样的语法那就太好了.
你说过.Result可能会带来僵局,我是否在实施你的解决方案时遗漏了什么?
Artists.PropertyChanged事件引发了以下消息:
我将试一试.ConfigureAwait(false),就像你在帖子中提到的那样,看看它是如何运作的.
忘了提,实际上我的实现使用.Result确实不会阻止UI,因为获得结果的典型时间是几秒钟; 我已经看到UI冻结了.这似乎是正确的......但我不确定它是否正确,因此我的问题.
正如其他人所说,WPF类型中的"异步"成员与async和无关await.
你的绑定确实有问题; 您的路径正在使用Task.Result,这将阻止UI线程,直到查询完成.此外,使用我Result带来了我在博客上描述的死锁的可能性.
我有另一个博客条目处理async属性,特别是如何数据绑定到(逻辑上)异步的属性.我的AsyncEx库有一个名为NotifyTaskCompletion的类型,允许您更自然地将数据绑定到异步Task.
所以,例如,你可以这样做:
public class HottestPageProxy
{
public HottestPageProxy()
{
Artists = NotifyTaskCompletion.Create(GetArtists());
}
public INotifyTaskCompletion<ArtistsQuery> Artists { get; private set; }
private Task<ArtistsQuery> GetArtists()
{
string apiKey = App.GetApiKey();
return Queries.ArtistTopHottt(new ArtistTopHotttParameters
{
ApiKey = apiKey,
Results = 100,
Buckets = new[] {ArtistTopHotttBuckets.Hotttnesss}
});
}
}
Run Code Online (Sandbox Code Playgroud)
然后你就可以将数据绑定到几个不同的属性INotifyTaskCompletion<T>,包括IsCompleted,ErrorMessage和Result(它没有阻止,它将返回default(T)如果任务未完成).
| 归档时间: |
|
| 查看次数: |
2676 次 |
| 最近记录: |