【问题标题】:Call UI thread in HttpWebRequest.BeginGetResponse在 HttpWebRequest.BeginGetResponse 中调用 UI 线程
【发布时间】:2015-02-27 09:15:39
【问题描述】:

晚安,我正在尝试调用 UI 线程来更新属性,实际上是在 HttpWebRequest.BeginGetResponse 方法中使用 CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync 方法。但它不起作用,我不知道它实际上是如何工作的。有我的代码:

private void DebutReponse(IAsyncResult resultatAsynchrone)
    {
        HttpWebRequest requete = (HttpWebRequest)resultatAsynchrone.AsyncState;
        Stream postStream = requete.EndGetRequestStream(resultatAsynchrone);

        string donneesAEnvoyer = "username=" + Name + "&password=" + Password + "&email=" + Email;

        string lol = donneesAEnvoyer;
        byte[] tableau = Encoding.UTF8.GetBytes(donneesAEnvoyer);
        postStream.Write(tableau, 0, donneesAEnvoyer.Length);
        postStream.Close();
        requete.BeginGetResponse(FinReponse, requete);
    }

    private void FinReponse(IAsyncResult resultatAsynchrone)
    {
        HttpWebResponse aResp = null;
        try
        {
            HttpWebRequest requete = (HttpWebRequest)resultatAsynchrone.AsyncState;
            WebResponse webResponse = requete.EndGetResponse(resultatAsynchrone);
            Stream stream = webResponse.GetResponseStream();

            StreamReader streamReader = new StreamReader(stream);
            string reponse = streamReader.ReadToEnd();
            stream.Close();
            streamReader.Close();
            webResponse.Close();

            //ErrorGridHeight = new GridLength(0.3, GridUnitType.Star);
            ErrorMsg = msgSucceed;
         }
        catch (WebException e)
        {
            if (e.Response != null)
            {
                aResp = e.Response as HttpWebResponse;
            }
        }
        if (aResp != null)
            await errorFunc();
    }

    private async Task errorFunc()
    {
        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => ErrorMsg = msgFailed);
    }

我有一个错误告诉我,我只能在返回 Taskasync 方法中使用 await 运算符。我不知道它是如何工作的。

编辑: 好的,所以我稍微更改了代码以避免此功能的问题:

requete.BeginGetResponse(FinReponse, requete);

因为她想要一个具有特定原型的函数,所以我这样做了:

private async Task lol(IAsyncResult resultatAsynchrone)
    {
        HttpWebResponse aResp = null;
        try
        {
            HttpWebRequest requete = (HttpWebRequest)resultatAsynchrone.AsyncState;
            WebResponse webResponse = requete.EndGetResponse(resultatAsynchrone);
            Stream stream = webResponse.GetResponseStream();

            StreamReader streamReader = new StreamReader(stream);
            string reponse = streamReader.ReadToEnd();
            stream.Close();
            streamReader.Close();
            webResponse.Close();

            //ErrorGridHeight = new GridLength(0.3, GridUnitType.Star);
            ErrorMsg = msgSucceed;
        }
        catch (WebException e)
        {
            if (e.Response != null)
            {
                aResp = e.Response as HttpWebResponse;
            }
        }
        if (aResp != null)
            await errorFunc();        
    }

    private void FinReponse(IAsyncResult resultatAsynchrone)
    {
        Task.Run(() => lol(resultatAsynchrone));
    }

    private async Task errorFunc()
    {
        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => ErrorMsg = msgFailed);
    }

唯一的问题是它不会改变属性,它不会进入我的属性集。我有一个例外是:

System.NotImplementedExeption

感谢您的帮助。

【问题讨论】:

  • “我不知道它是如何工作的” 那么在这里问一个问题可能是个坏主意。最好先尝试通过阅读在线文档、教程等来理解 async/await。
  • 是的,我刚刚看了,msdn.microsoft.com/fr-fr/library/hh191443.aspx 但我不确定是否完全理解示例中的所有步骤。我想练习也许能更好地理解。

标签: c# wpf multithreading windows-phone httpwebrequest


【解决方案1】:

尝试将您的errorFunc() 更改为此。

private void errorFunc()
{
    CoreApplication.MainView.CoreWindow.Dispatcher.BeginInvoke(() =>
    {
        ErrorMsg = msgFailed;
    });
}

我还发现了另一个地方,您试图在不调用 UI 线程的情况下更改 ErrorMsg。这是代码ErrorMsg = msgSucceed; 的行。我建议使用相同的方式,因此将行替换为:

CoreApplication.MainView.CoreWindow.Dispatcher.BeginInvoke(() =>
{
    ErrorMsg = msgSucceed;
});

【讨论】:

  • 在我使用这种方法之前,但现在我改变了项目,我不确定它到底是什么,可能像 Silverlight 应用程序,我没有这个 PERFECT 方法 BeginInvock 了。谢谢。
【解决方案2】:

您必须执行FinReponse 方法async 才能在其中使用await 运算符:

private async void FinReponse(IAsyncResult resultatAsynchrone)

【讨论】:

  • 是的,我试过了,但我想我不能改变它,因为这个方法:requete.BeginGetResponse(FinReponse, requete);需要,想想,一个特定的原型,它不适合。
【解决方案3】:

所以我找到了访问 UI 的答案,我必须使用:

            Deployment.Current.Dispatcher.BeginInvoke(()=>mym());

而且效果很好。 谢谢你的一切。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 1970-01-01
    • 2012-11-24
    • 2019-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多