Windows phone 7 在异步web请求回调中未更新UI
我正在使用它进行web请求并下载一些数据: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
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。试用过。结果是一样的。我想我们正在处理测试版中引入的一个更大的错误。至少这意味着它很可能会工作。)在设备上。但是令人沮丧!