当前位置:编程学习 > wap >>

Windows phone中的循环异步请求网络时的线程问题

最近遇到这样一个问题,主体代码如下。目的是遍历一个list,从中取出id,然后用这个id去请求网络,得到返回数据并保存至数据库。但因为ResponseCallback是一个异步的过程,所以一直会产生这样一个异常:InvalidOperationException “The operation cannot be performed because an operation on another thread has not been completed.”
这种问题应该很常见,求指点。
代码:
foreach (var item in list)
{
GetResult(item.id);
}

void GetResult(string id)
{
string url = "http://xxxx" + id;
HttpWebRequest request = WebRequest.CreateHttp(new Uri(url));
request.BeginGetResponse(ResponseCallback, request);
}
private void ResponseCallback(IAsyncResult ar)
{
//将请求得到的数据保存至数据库中
}
windowsphone 循环请求网络 异步 HttpWebRequest  InvalidOperation --------------------编程问答-------------------- 你便利执行的是GetResult吗?如果是

用lambda把ResponseCallback放到GetResult“内” --------------------编程问答-------------------- 偶百度了下,你这个问题是ResponseCallback里面几个线程同时访问了数据库导致了异常,HttpWebRequest虽然只有异步方式,但是可以用AutoResetEvent模拟出同步的方式,参考这货的例子http://www.silverlightchina.net/html/zhuantixilie/winphone7/2012/0906/18689.html
可以让这些请求一个一个执行。

然后我记得,多个线程访问同一个代码段的时候,可以用lock什么的锁住,同一个对象可以用Monitor锁住,这是另一种思路,你可以试试看看 --------------------编程问答--------------------
引用 1 楼 NianHui 的回复:
你便利执行的是GetResult吗?如果是

用lambda把ResponseCallback放到GetResult“内”

嗯,这个方法试过,完全没有用。 --------------------编程问答--------------------
引用 2 楼 lixygibli 的回复:
偶百度了下,你这个问题是ResponseCallback里面几个线程同时访问了数据库导致了异常,HttpWebRequest虽然只有异步方式,但是可以用AutoResetEvent模拟出同步的方式,参考这货的例子http://www.silverlightchina.net/html/zhuantixilie/winphone7/2012/0906/18689.html
可以让这些请求一个一个执行。

然后我记得,多个线程访问同一个代码段的时候,可以用lock什么的锁住,同一个对象可以用Monitor锁住,这是另一种思路,你可以试试看看

说到重点了。 --------------------编程问答-------------------- 我去,才发现是你,就不告诉你我是谁哈哈 --------------------编程问答--------------------
引用 5 楼 lixygibli 的回复:
我去,才发现是你,就不告诉你我是谁哈哈


???????????????? --------------------编程问答--------------------
引用 3 楼 aidyliuliu 的回复:
Quote: 引用 1 楼 NianHui 的回复:

你便利执行的是GetResult吗?如果是

用lambda把ResponseCallback放到GetResult“内”

嗯,这个方法试过,完全没有用。

void GetResult(string id)
 {
 string url = "http://xxxx" + id;
 HttpWebRequest request = WebRequest.CreateHttp(new Uri(url));
 request.BeginGetResponse(ResponseCallback, request);
 }
 private void ResponseCallback(IAsyncResult ar)
 {
 //将请求得到的数据保存至数据库中
}

把这两个方法封装到一个类里面,
foreach (var item in list)
 {
     xxxClass x=new xxxClass(item.id);
     x.GetResult();
 }


另外我觉得你应该从接口上下手,不是每次传递1个id,而是传一个id集合,让一个请求搞定。 --------------------编程问答-------------------- 在类级别加一个变量Object lockObject=new Object();

在completed方法中一下
lock(lockObject)
{
try
{}
catct()
{..}
} --------------------编程问答--------------------
引用 7 楼 NianHui 的回复:
Quote: 引用 3 楼 aidyliuliu 的回复:

Quote: 引用 1 楼 NianHui 的回复:

你便利执行的是GetResult吗?如果是

用lambda把ResponseCallback放到GetResult“内”

嗯,这个方法试过,完全没有用。

void GetResult(string id)
 {
 string url = "http://xxxx" + id;
 HttpWebRequest request = WebRequest.CreateHttp(new Uri(url));
 request.BeginGetResponse(ResponseCallback, request);
 }
 private void ResponseCallback(IAsyncResult ar)
 {
 //将请求得到的数据保存至数据库中
}

把这两个方法封装到一个类里面,
foreach (var item in list)
 {
     xxxClass x=new xxxClass(item.id);
     x.GetResult();
 }


另外我觉得你应该从接口上下手,不是每次传递1个id,而是传一个id集合,让一个请求搞定。

这样封装成一个class,每次循环就实例化出一个对象,对象的方法同样是调用HttpWebRequest获取异步回调,这和之前的直接调用有什么区别,这个方法我没试。
还有,传一个id的集合请求网络,还是要一个个都遍历获返回值的呀,这地方不大明白你的意思。 --------------------编程问答--------------------
引用 9 楼 aidyliuliu 的回复:
这样封装成一个class,每次循环就实例化出一个对象,对象的方法同样是调用HttpWebRequest获取异步回调,这和之前的直接调用有什么区别,这个方法我没试。
还有,传一个id的集合请求网络,还是要一个个都遍历获返回值的呀,这地方不大明白你的意思。


试试先。
传id集合,你请求的时候就不用发多个请求了吧,一个请求就可以了。也就不会有你现在出现的问题了。
补充:移动开发 ,  Windows Phone
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,