Windows phone 7 在异步web请求回调中未更新UI

Windows phone 7 在异步web请求回调中未更新UI,windows-phone-7,Windows Phone 7,我正在使用它进行web请求并下载一些数据: public partial class MainPage : PhoneApplicationPage { public MainPage() { InitializeComponent(); var client = new WebClient(); client.DownloadStringCompleted += (s, e) => { textB

我正在使用它进行web请求并下载一些数据:

public partial class MainPage : PhoneApplicationPage
{
    public MainPage()
    {
        InitializeComponent();

        var client = new WebClient();

        client.DownloadStringCompleted += (s, e) => {
            textBlock1.Text = e.Result;
        };

        client.DownloadStringAsync(new Uri("http://example.com"));
    }
}
textBlock1
的文本永远不会更改,即使
e.Result
具有正确的数据。我如何从回调中更新它

编辑:如果我添加
MessageBox.Show(e.Result)
在回调和textBlock1.Text赋值中,消息框和文本框都显示正确的数据


再次编辑:如果我添加一个文本框并将其文本设置在textBlock1.text行之后,它们都会显示正确的文本。

client.DownloadStringAsync需要如下Uri:

client.DownloadStringAsync(new Uri("http://example.com"));
    client.DownloadStringCompleted += (s, e) => 
    { 
        if (null == e.Error) 
            Dispatcher.BeginInvoke(() => UpdateStatus(e.Result)); 
        else 
            Dispatcher.BeginInvoke(() => UpdateStatus("Operation failed: " + e.Error.Message)); 
    };
另外,您不应该通过Dispatcher.BeginInvoke这样更新TextBlock吗:

client.DownloadStringAsync(new Uri("http://example.com"));
    client.DownloadStringCompleted += (s, e) => 
    { 
        if (null == e.Error) 
            Dispatcher.BeginInvoke(() => UpdateStatus(e.Result)); 
        else 
            Dispatcher.BeginInvoke(() => UpdateStatus("Operation failed: " + e.Error.Message)); 
    };

我想,这是一个bug。

我想发表评论,但还不能。是的,我有一个非常相似的问题。在我的例子中,更新DownloadStatus属性的是我的viewmodel,当下载完成后,我会做更多的工作并继续更新此属性

public partial class MainPage : PhoneApplicationPage
{
    public MainPage()
    {
        InitializeComponent();

        Loaded += MainPage_Loaded;
    }

    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        var dispatcher = Deployment.Current.Dispatcher;

        var client = new WebClient();

        client.DownloadStringCompleted += (s, e) =>
        {
            var result = e.Result;
            dispatcher.BeginInvoke(
                ()=> textBlock1.Text = result
                );
        };

        client.DownloadStringAsync(new Uri("http://example.com"));
    }
}
一旦ViewModel代码点击OpenReadCompleted方法,视图就会停止更新。我已经仔细阅读了代码。PropertyChanged激发,视图甚至返回并检索新的属性值,但从未显示更改

我确信这是一个bug,但后来我创建了一个全新的项目来重现这个问题,而且效果很好

这是我的一段不可复制代码。绑定到“DownloadStatus”的UI文本块在整个过程中都能正确更新。但同样的模式在我的主要项目中不起作用。气死我了

public void BeginDownload(bool doWorkAfterDownload)
{
    DownloadStatus = "Starting ...";

    _doExtraWork = doWorkAfterDownload;
    var webClient = new WebClient();

    string auth = "Basic " + Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("test:password"));
    webClient.Headers["Authorization"] = auth;

    webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webClient_DownloadProgressChanged);
    webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);

    webClient.OpenReadAsync(new Uri("http://www.ben.geek.nz/samsung1.jpg"));
}

void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
    if (e.Error != null)
    {
        DownloadStatus = e.Error.Message;
        return;
    }

    DownloadStatus = "Completed. Idle.";

    if(_doExtraWork)
    {
        Thread t = new Thread(DoWork);
        t.Start(e.Result);
    }

}

void DoWork(object param)
{
    InvokeDownloadCompleted(new EventArgs());

    // just do some updating
    for (int i = 1; i <= 10; i++)
    {
        DownloadStatus = string.Format("Doing work {0}/10", i);
        Thread.Sleep(500);
    }
    DownloadStatus = "Completed extra work. Idle.";
    InvokeExtraWorkCompleted(new EventArgs());
}
publicvoid开始下载(booldoworkafterdownload)
{
DownloadStatus=“正在启动…”;
_DoExtrawWork=doWorkAfterDownload;
var webClient=新的webClient();
string auth=“Basic”+Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(“测试:密码”);
webClient.Headers[“Authorization”]=auth;
webClient.DownloadProgressChanged+=新的DownloadProgressChangedEventHandler(webClient\u DownloadProgressChanged);
webClient.OpenReadCompleted+=新的OpenReadCompletedEventHandler(webClient\u OpenReadCompleted);
webClient.OpenReadAsync(新Uri(“http://www.ben.geek.nz/samsung1.jpg"));
}
void webClient\u OpenReadCompleted(对象发送方,OpenReadCompletedEventArgs e)
{
如果(例如错误!=null)
{
DownloadStatus=e.Error.Message;
返回;
}
DownloadStatus=“已完成。空闲。”;
如果(_doExtraWork)
{
螺纹t=新螺纹(定位销);
t、 开始(即结果);
}
}
void DoWork(对象参数)
{
InvokedDownloadCompleted(新事件参数());
//只是做一些更新

对于(int i=1;i我在从不同的调度程序更新UI时也遇到了一些问题。我最后做的是使用TextBlock的(或其他UI元素)自己的dispatcher,这对我很有用。我认为手机框架可能在应用程序和UI元素之间使用了不同的dispatcher。请注意从dispatcher.BeginInvoke到textbox1.dispatcher的更改

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    var dispatcher = Deployment.Current.Dispatcher;

    var client = new WebClient();

    client.DownloadStringCompleted += (s, e) =>
    {
        var result = e.Result;
        textBlock1.Dispatcher.BeginInvoke(
            ()=> textBlock1.Text = result
            );
    };

    client.DownloadStringAsync(new Uri("http://example.com"));
}

通过浏览WP7论坛,一些人报告说这与视频卡驱动程序问题有关。我已将ATI Radeon HD 3400驱动程序更新为最新版本,现在似乎可以正常工作。

更新了错误的示例代码。Dispatcher.BeginInvoke可能是我的目标。我是WP7新手。有任何示例吗?尝试使用Dispatcher.BeginInvoke仍然不起作用。没有更新。e.Result仍然有正确的数据。我认为BeginInvoke不应该是必要的,因为DownloadStringCompleted事件在UI线程中引发。我假设那里有输入错误,您的真实代码是:client.DownloadStringCompleted+=(s,e)=>{textBlock1.Text=e.Result;};对吗?是的,修复了。谢谢。过于热情的退格:)John-出于兴趣,请将您的代码移动到“已加载”的事件处理程序中。只是想看看它是否是构造函数独有的。尝试使用PhoneApplicationPage_加载,但不起作用:(我也开始这么想了。我刚刚用一个WPF导航应用程序试用过,效果很好。我和Dispatcher尝试了两个不同的组合,但我会再试试你的组合,看看有什么不同。谢谢Daniel。试用过。结果是一样的。我想我们正在处理测试版中引入的一个更大的错误。至少这意味着它很可能会工作。)在设备上。但是令人沮丧!