如何从Windows Phone中的工作线程中的UI线程获取值?

时间:2014-11-09 22:55:51

标签: c# multithreading windows-phone-8 dispatcher ui-thread

我想在我的windows phone 8 app中使用POST方法调用RESTfull服务。所以我需要在将其解析为JSON之后插入我想要在请求正文中发送的数据。为此,我使用了以下代码:

enter cprivate void NextArrow_Tap(object sender, System.Windows.Input.GestureEventArgs e)
    {
        if (!String.IsNullOrEmpty(TxtBox_mail.Text))
        {
           Uri myUri = new Uri("http://myUri");
           HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(myUri);
           myRequest.Method = "POST";
           myRequest.ContentType = "application/json";
           myRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), myRequest);


        }
    }


    public void GetRequestStreamCallback(IAsyncResult callbackResult)
    {
        byte[] byteArray = null;
        HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;

        // End the stream request operation
        Stream postStream = myRequest.EndGetRequestStream(callbackResult);

        // Create the post data
        Dispatcher.BeginInvoke(() =>
        {
            string mailToCheck = TxtBox_mail.Text.ToString();
            string postData = JsonConvert.SerializeObject(mailToCheck);
            byteArray = Encoding.UTF8.GetBytes(postData);
        });


        // Add the post data to the web request
        postStream.Write(byteArray, 0, byteArray.Length);
        postStream.Close();

        // Start the web request
        myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallback), myRequest);
    }

我已使用调度程序获取UI线程上文本框控件的值,但 byteArray 始终为 null 。有人知道这里有什么问题吗?提前谢谢。

1 个答案:

答案 0 :(得分:3)

主要问题是您使用的是异步BeginInvoke()方法,该方法会立即返回。调用的委托直到稍后才执行,因此当前线程继续尝试写入数据时,byteArray变量仍然为空。

解决此问题的一种方法是使用Invoke()方法。那个方法是同步的;也就是说,在调用的代码完成之前,它不会返回。

恕我直言,更好的解决方法是使用async / await模式。这看起来像这样:

async void NextArrow_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
    if (!String.IsNullOrEmpty(TxtBox_mail.Text))
    {
       Uri myUri = new Uri("http://myUri");
       HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(myUri);

       myRequest.Method = "POST";
       myRequest.ContentType = "application/json";

       Stream postStream = await myRequest.GetRequestStreamAsync();
       HttpWebResponse response = await GetRequestStreamCallback(postStream, myRequest);

       // await GetResponsetStreamCallback(response) here...the
       // method wasn't shown in the original question, so I've left
       // out the particulars, as an exercise for the reader. :)
    }
}


async void GetRequestStreamCallback(Stream postStream, WebRequest myRequest)
{
    byte[] byteArray = null;

    // Create the post data
    string mailToCheck = TxtBox_mail.Text.ToString();
    string postData = JsonConvert.SerializeObject(mailToCheck);
    byteArray = Encoding.UTF8.GetBytes(postData);

    // Add the post data to the web request
    postStream.Write(byteArray, 0, byteArray.Length);
    postStream.Close();

    // Start the web request
    return await myRequest.GetResponseAsync();
}

正如您所看到的,以这种方式执行此操作允许以简单,直接和顺序的方式编写代码的主流,从而更容易查看执行流的位置,并简化逻辑的表达整体。