Windows phone 8 等待异步操作结束Windows Phone

Windows phone 8 等待异步操作结束Windows Phone,windows-phone-8,asynchronous,Windows Phone 8,Asynchronous,我试图解析从服务器下载的xml中的一些POI,我看到它是在程序在主线程中继续之后完成的。我还没有找到解决它的方法,因为我需要它 using System.Threading; namespace XML_Parser { class XMLParserPOI_Wiki { private static XMLParserPOI_Wiki objSingle = new XMLParserPOI_Wiki(); public static XMLP

我试图解析从服务器下载的xml中的一些POI,我看到它是在程序在主线程中继续之后完成的。我还没有找到解决它的方法,因为我需要它

using System.Threading;

namespace XML_Parser
{
    class XMLParserPOI_Wiki
    {
        private static XMLParserPOI_Wiki objSingle = new XMLParserPOI_Wiki();
        public static XMLParserPOI_Wiki ObjSingle
        {
            get { return objSingle; }
            set { objSingle = value; }
        }
        private List<POI> places;
        public List<POI> Places
        {
            get { return places; }
        }
        private XMLParserPOI_Wiki()
        {

        }



        public void parseWikitude(string url)
        {
            places = new List<POI>();
            WebClient wc = new WebClient();
            wc.DownloadStringCompleted += HttpsCompleted;
            wc.DownloadStringAsync(new Uri(url));            
        }

        private void HttpsCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                XDocument xdoc = XDocument.Parse(e.Result, LoadOptions.None);
                XNamespace ns = "http://www.opengis.net/kml/2.2";
                XNamespace ns2 = "http://www.openarml.org/wikitude/1.0";
                var placemarkers = xdoc.Root.Descendants(ns + "Placemark");
                places =
                (from query in xdoc.Root.Descendants(ns + "Placemark")
                 select new POI
                 (
                   ...
                 )).ToList();
                System.Diagnostics.Debug.WriteLine("Lista");
                System.Diagnostics.Debug.WriteLine(places.Count);

            }
        }

    }
}
使用系统线程;
名称空间XML_解析器
{
类XMLParserPOI_Wiki
{
私有静态XMLParserPOI_Wiki objSingle=new XMLParserPOI_Wiki();
公共静态XMLParserPOI_Wiki对象
{
获取{return objSingle;}
设置{objSingle=value;}
}
私人名单;
公众地方名单
{
获取{返回位置;}
}
私有XMLParserPOI_Wiki()
{
}
公共void(字符串url)
{
位置=新列表();
WebClient wc=新的WebClient();
wc.DownloadStringCompleted+=HttpsCompleted;
DownloadStringAsync(新Uri(url));
}
私有void HttpsCompleted(对象发送方,下载StringCompletedEventArgs e)
{
如果(e.Error==null)
{
XDocument xdoc=XDocument.Parse(例如,Result,LoadOptions.None);
XNS=”http://www.opengis.net/kml/2.2";
XNS2=”http://www.openarml.org/wikitude/1.0";
var placemarkers=xdoc.Root.substands(ns+“Placemark”);
地点=
(来自xdoc.Root.substands(ns+“Placemark”)中的查询)
选择新POI
(
...
)).ToList();
System.Diagnostics.Debug.WriteLine(“Lista”);
系统.Diagnostics.Debug.WriteLine(places.Count);
}
}
}
}
在我的主课上:

XMLParserPOI_Wiki parserXML = XMLParserPOI_Wiki.ObjSingle;

        parserXML.parseWikitude("http://myurl.php");
        System.Diagnostics.Debug.WriteLine("Lista de pois");
        System.Diagnostics.Debug.WriteLine(parserXML.Places.Count);
        for (int i = 0; i < parserXML.Places.Count; i++)
        {
            System.Diagnostics.Debug.WriteLine(parserXML.Places[i].getName());
        }
XMLParserPOI_Wiki parserXML=XMLParserPOI_Wiki.ObjSingle;
parserXML.parseWikitude(“http://myurl.php");
系统.诊断.调试.写入线(“Lista de pois”);
System.Diagnostics.Debug.WriteLine(parserXML.Places.Count);
for(int i=0;i
它在Lista和X(POI数量)之前打印Lista de POI和0

我想我应该冻结主线程,但我用一些示例尝试了几次,但都没有成功


你能给我指一下这方面的教程吗?除了得到答案之外,我还想了解如何处理此类操作。首先,你不想阻止(冻结)UI线程

这称为异步编程。你可以做两件事来解决你的问题(我建议选择2!):

  • 使用经典的回调模型。基本上,在后台线程上调用一些长操作,并为其提供一个函数,以便在长操作完成时执行。以下是如何在你的情况下做到这一点

    HttpsCompleted
    方法的末尾,使用以下命令调用UI线程上所需的内容:

    Deployment.Current.Dispatcher.BeginInvoke(delegate() {
        //The code here will be invoked on the UI thread
    });
    
    如果要使
    parseWikitude
    方法可重用,应该向其传递一个操作。通过这种方式,您可以从多个位置调用它,并告诉它在完成解析时在UI线程上执行什么操作。大概是这样的:

    public void parseWikitude(string url, Action callback) {
        places = new List<POI>();
        WebClient wc = new WebClient();
        wc.DownloadStringCompleted += HttpsCompleted;
        wc.DownloadStringAsync(new Uri(url), callback);
    }
    
    private void HttpsCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            ...
    
            var callback = (Action)e.UserState;
            Deployment.Current.Dispatcher.BeginInvoke(callback);
        }
    }
    
    //And then when you use it, you do it like that
    parserXML.parseWikitude("http://myurl.php", delegate() {
       //The code here will be executed on the UI thread, after the parsing is done 
    });
    
    public-void-parseWikitude(字符串url,动作回调){
    位置=新列表();
    WebClient wc=新的WebClient();
    wc.DownloadStringCompleted+=HttpsCompleted;
    DownloadStringAsync(新Uri(url),回调);
    }
    私有void HttpsCompleted(对象发送方,下载StringCompletedEventArgs e)
    {
    如果(e.Error==null)
    {
    ...
    var callback=(Action)e.UserState;
    Deployment.Current.Dispatcher.BeginInvoke(回调);
    }
    }
    //然后当你使用它时,你就这样做了
    parserXML.parseWikitude(“http://myurl.php“,delegate(){
    //解析完成后,这里的代码将在UI线程上执行
    });
    
  • 在.NET中使用(而不是)新的asnyc模式。你应该读一下这篇文章,如果你问我的话,这是.NET最好的功能之一。:)它基本上自动执行回调操作,使代码更易于阅读/维护/使用。一旦你习惯了,就是这样

    下面是一个例子:

    public Task<List<POI>> parseWikitude(string url) {
        TaskCompletionSource<List<POI>> resultTaskSource = new TaskCompletionSource<List<POI>>();
    
        WebClient wc = new WebClient();
        wc.DownloadStringCompleted += HttpsCompleted;
        wc.DownloadStringAsync(new Uri(url), resultTaskSource);
    
        return resultTaskSource.Task;
    }
    
    private void HttpsCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            //If needed, run the code here in a background thread
            //...
    
            var resultTaskSource = (TaskCompletionSource<List<POI>>)e.UserState;
            resultTaskSource.SetResult(places);
        }
    }
    
    //And when you need to use it, do it like that (note, this must be invoked in an async method!)
    var places = await parser.parseWikitude("http://myurl.php");
    //The code here will be executed on the same thread when the parsing is done, but the thread will not be blocked while the download is happening.
    
    公共任务解析(字符串url){
    TaskCompletionSource resultTaskSource=新TaskCompletionSource();
    WebClient wc=新的WebClient();
    wc.DownloadStringCompleted+=HttpsCompleted;
    DownloadStringAsync(新Uri(url),resultTaskSource);
    返回resultTaskSource.Task;
    }
    私有void HttpsCompleted(对象发送方,下载StringCompletedEventArgs e)
    {
    如果(e.Error==null)
    {
    //如果需要,在后台线程中运行这里的代码
    //...
    var resultTaskSource=(TaskCompletionSource)e.UserState;
    resultTaskSource.SetResult(位置);
    }
    }
    //当您需要使用它时,可以这样做(注意,这必须在异步方法中调用!)
    var places=wait parser.parseWikitude(“http://myurl.php");
    //解析完成后,这里的代码将在同一线程上执行,但在下载过程中不会阻止该线程。
    
  • 所以,这是两种处理方法。选择一是老派,经典和简单。选项二是一种新的、很酷的异步方式。这真的是必须知道的。一旦你习惯了,就会简化很多事情


    另外,如果我得意忘形,我很抱歉D

    冻结主线程或UI线程不是一个好的做法。为什么不显示一个加载指示器呢?但是我怎么能在主线程中知道解析已经完成呢?使用一个指示符是个好主意。我猜解析在HttpsCompleted回调方法的末尾完成了,你不这么认为吗?谢谢,我现在会仔细阅读,然后我会尝试它,它会工作的。谢谢我会读更多关于这个任务和你们所说的内容。