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锁住,这是另一种思路,你可以试试看看 --------------------编程问答--------------------
嗯,这个方法试过,完全没有用。 --------------------编程问答--------------------
说到重点了。 --------------------编程问答-------------------- 我去,才发现是你,就不告诉你我是谁哈哈 --------------------编程问答--------------------
???????????????? --------------------编程问答--------------------
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()
{..}
} --------------------编程问答--------------------
你便利执行的是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的集合请求网络,还是要一个个都遍历获返回值的呀,这地方不大明白你的意思。 --------------------编程问答--------------------
这样封装成一个class,每次循环就实例化出一个对象,对象的方法同样是调用HttpWebRequest获取异步回调,这和之前的直接调用有什么区别,这个方法我没试。
还有,传一个id的集合请求网络,还是要一个个都遍历获返回值的呀,这地方不大明白你的意思。
试试先。
传id集合,你请求的时候就不用发多个请求了吧,一个请求就可以了。也就不会有你现在出现的问题了。
补充:移动开发 , Windows Phone