[英]How to get a complex type from async method
public ObservableCollection<Offer> ModelPersons
{
get
{
return _persons;
}
set
{
_persons = value;
RaisePropertyChanged(() => ModelPersons);
}
}
// How can I get the ObservableCollection<Person>
from the Task<ObservableCollection<Person>>
? //如何从
Task<ObservableCollection<Person>>
获取ObservableCollection<Person>
? Right now it's complaining about can not convert source type Task<Observable<Person>> to Observable<Person>
现在它抱怨无法将源类型
Task<Observable<Person>> to Observable<Person>
private void GetPersonOrders()
{
ModelPersons = _service.GetPersonOrders();
}
in Service Class: 在服务类:
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;
}
I recommend you use the NotifyTaskCompletion
type from my AsyncEx library . 我建议你使用我的AsyncEx库中的
NotifyTaskCompletion
类型 。
Then your code will look like this: 然后你的代码将如下所示:
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());
}
And your data binding will change from ModelPersons
to ModelPersons.Result
. 您的数据绑定将从
ModelPersons
更改为ModelPersons.Result
。
Further recommended reading: 进一步推荐阅读:
async
/ await
intro and its followup resources, specifically the TAP . async
/ await
介绍及其后续资源,特别是TAP 。 async
properties . async
属性的博客文章。 Since your method returns a Task<ObservableCollection<Person>>
you can get the result of the task via Result
property. 由于您的方法返回
Task<ObservableCollection<Person>>
您可以通过Result
属性获取任务的Result
。
private void GetPersonOrders()
{
ModelPersons = _service.GetPersonOrders().Result;
}
Keep in mind however, that accessing the Result
property will block the calling thread until the task completes, ie until you will receive the WebResponse
. 但请记住,访问
Result
属性将阻止调用线程,直到任务完成,即直到您将收到WebResponse
。
Another way would be to attach a continuation task to the task returned by your method using ContinueWith
. 另一种方法是使用
ContinueWith
将延续任务附加到方法返回的任务。 The continuation will set the property to the value returned from task. continuation将属性设置为从task返回的值。
private void GetPersonOrders()
{
_service.GetPersonOrders()
.ContinueWith(t => ModelPersons = t.Result);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.