c# - .Net BlockingCollection.Take(2) : Safely removing two items at a time -


after doing research, i'm resorting feedback regarding how remove 2 items off concurrent collection. situation involves incoming messages on udp being placed blockingcollection. once there 2 users in collection, need safely take 2 users , process them. i've seen several different techniques including ideas listed below. current implementation below i'm thinking there's cleaner way while ensuring users processed in groups of two. that's restriction in scenario.

current implementation:

    private int userqueuecount = 0;     public blockingcollection<user> userqueue = new blockingcollection<user>();      public void joinqueue(user u)     {            userqueue.add(u);            interlocked.increment(ref userqueuecount);             if (userqueuecount > 1)            {                ienumerable<user> users = userqueue.take(2);                if(users.count==2) {                  interlocked.decrement(ref userqueuecount);                  interlocked.decrement(ref userqueuecount);                  ... work users if 1                   removed i'll run problems                }             }     } 

what cannot test in production situation ensure integrity.

 parallel.foreach(userqueue.take(2), (u) => { ... }); 

or better yet:

    public void joinqueue(user u)     {            userqueue.add(u);            // if needed? increment            interlocked.increment(ref userqueuecount);            userqueue.completeadding();     } 

then implement somewhere:

        task.factory.startnew(() =>         {             while (userqueuecount > 1) or (userqueue.count > 1) if it's safe?             {                 ienumerable<user> users = userqueue.take(2);                 ... stuff             }          }); 

the problem i'm not sure can guarantee between condition (count > 1) , take(2) i'm ensuring userqueue has @ least 2 items process? incoming udp messages processed in parallel need way safely pull items off of blocking/concurrent collection in pairs of two.

is there better/safer way this?

revised comments: intented goal of question achieve stable/thread safe method of processing items off of concurrent collection in .net 4.0. doesn't have pretty, has stable in task of processing items in unordered pairs of twos in parallel environment.

here i'd in rough code:

concurrentqueuequeue = new concurrentqueue(); //can use blockingcollection (as it's blocking concurrentqueue default anyway)  public void onuserstartedgame(user joininguser) {    user waitinguser;    if (this.gamequeue.trydequeue(out waitinguser)) //if there's waiting, we'll him       this.matchusers(waitinguser, joininguser);    else       this.queueuser(joininguser); //it doesn't matter if there's in queue because, well, using queue , sort out. }  private void queueuser(user user) {    this.gamequeue.enqueue(user); }  private void matchusers(user first, user second) {    //not sure here } 

the basic idea being if someone's wants start game , there's in queue, match them , start game - if there's no-one, add them queue. @ best you'll have 1 user in queue @ time, if not, well, that's not bad either because other users start games, waiting ones gradually removed , no new ones added until queue empty again.


Comments

Popular posts from this blog

java - Play! framework 2.0: How to display multiple image? -

gmail - Is there any documentation for read-only access to the Google Contacts API? -

php - Controller/JToolBar not working in Joomla 2.5 -