c# - Why does the synchronized wrapper for ArrayList not work? -
i have generated proxy classes web service in vusual studio 'add web reference'. generated rtwebservice
class has method setvalueasync
. extended class , added setvaluerequest
keeps track of requests , cancels pending requests when error occurs. every request store userstate
object in arraylist created follows:
requests = arraylist.synchronized(new arraylist());
i created method:
public void cancelpendingrequests() { lock (requests.syncroot) { if (requests.count > 0) { foreach (object request in requests) { this.cancelasync(request); } requests.clear(); } } }
i call method when request returns on setvaluecompleted
event:
private void onrequestcomplete( object sender, service.setvaluecompletedeventargs args ) { lock (syncresponse) { if (args.cancelled) { return; } if (args.userstate != null) { requests.remove(args.userstate); } if (args.error != null) { cancelpendingrequests(); } } }
to start new request call:
public void setvaluerequest(string tag, string value) { var request = new object(); this.setvalueasync(tag, value, request); requests.add(request); }
everytime make request , @ same time response returns error, targetinvocationexception
in cancelpendingrequests
. inner exception invalidoperationexception
on arraylist in cancelpendingrequests
method saying:
collection modified; enumeration operation may not execute.
so seems setvaluerequest
has modified requests
object while enumerating it. thought impossible because used synchronized wrapper arraylist , use syncroot synchronize enumeration. i'm bit stuck on if has idea?
never use syncroot it's inherently broken. (if share list invite deadlock)
don't use arraylist, should marked "deprecated".
arraylist.synchronized return's works more not thread safe, i.e. it's not thread safe during set of operations.
you can either use system.collection.concurrent, or use readerwriterlockslim
Comments
Post a Comment