[英]How to get a complex type from async method
public ObservableCollection<Offer> ModelPersons
{
get
{
return _persons;
}
set
{
_persons = value;
RaisePropertyChanged(() => ModelPersons);
}
}
//如何从Task<ObservableCollection<Person>>
获取ObservableCollection<Person>
? 现在它抱怨无法将源类型Task<Observable<Person>> to Observable<Person>
private void GetPersonOrders()
{
ModelPersons = _service.GetPersonOrders();
}
在服务类:
private ObservableCollection<Person> _modelPersons;
public async Task<ObservableCollection<Person>> GetPersonOrders()
{
var req =
WebRequest.Create(
"http....")
as HttpWebRequest;
if (req == null) return null;
req.KeepAlive = false;
req.Method = "GET";
req.ContentType = "text/xml; encoding='utf-8'";
WebResponse response = req.GetResponse();
Stream receiveStream = response.GetResponseStream();
Encoding encode = Encoding.GetEncoding("utf-8");
string message = null;
if (receiveStream != null)
using (var readStream = new StreamReader(receiveStream, encode))
{
var result = new char[256];
int count = await readStream.ReadAsync(result, 0, 256);
while (count > 0)
{
var value = new String(result, 0, count);
message += value;
count = await readStream.ReadAsync(result, 0, 256);
}
var stringReader = new StringReader(message);
_modelPersons= new ObservableCollection<Person>();
var xmlTextReader = new XmlTextReader(stringReader);
xmlTextReader.WhitespaceHandling = WhitespaceHandling.None;
Person person = null;
string element = "";
while (xmlTextReader.Read())
{
if (xmlTextReader.NodeType == XmlNodeType.Element)
{
element = xmlTextReader.Name;
}
else if (xmlTextReader.NodeType == XmlNodeType.Text)
{
switch (element)
{
case "name":
person = new Person { Name = xmlTextReader.Value };
_modelPersons.Add(person);
break;
}
}
}
}
return _modelPersons;
}
我建议你使用我的AsyncEx库中的NotifyTaskCompletion
类型 。
然后你的代码将如下所示:
private INotifyCompletion<ObservableCollection<Offer>> _persons;
public INotifyCompletion<ObservableCollection<Offer>> ModelPersons
{
get { return _persons; }
set
{
_persons = value;
RaisePropertyChanged(() => ModelPersons);
}
}
private void GetPersonOrders()
{
ModelPersons = NotifyCompletion.Create(_service.GetPersonOrdersAsync());
}
您的数据绑定将从ModelPersons
更改为ModelPersons.Result
。
进一步推荐阅读:
async
/ await
介绍及其后续资源,特别是TAP 。 async
属性的博客文章。 由于您的方法返回Task<ObservableCollection<Person>>
您可以通过Result
属性获取任务的Result
。
private void GetPersonOrders()
{
ModelPersons = _service.GetPersonOrders().Result;
}
但请记住,访问Result
属性将阻止调用线程,直到任务完成,即直到您将收到WebResponse
。
另一种方法是使用ContinueWith
将延续任务附加到方法返回的任务。 continuation将属性设置为从task返回的值。
private void GetPersonOrders()
{
_service.GetPersonOrders()
.ContinueWith(t => ModelPersons = t.Result);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.