Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 927641
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T19:53:07+00:00 2026-05-15T19:53:07+00:00

System.Collections.Concurrent has some new collections that work very well in multithreaded environments. However, they

  • 0

System.Collections.Concurrent has some new collections that work very well in multithreaded environments. However, they are a bit limited. Either they block until an item becomes available, or they return default(T) (TryXXX methods).

I’m needing a collection that is thread safe, but instead of blocking the calling thread it uses a callback to inform me that at least one item is available.

My current solution is to use a BlockingCollection, but to use the APM with a delegate to get the next element. In other words, I create a delegate to a method that Takes from the collection, and execute that delegate using BeginInvoke.

Unfortunately, I have to keep a lot of state within my class in order to accomplish this. Worse, the class is not thread safe; it can only be used by a single thread. I’m skirting the edge of maintainability, which I’d prefer not to do.

I know there are some libraries out there that make what I’m doing here pretty simple (I believe the Reactive Framework is one of these), but I’d like to accomplish my goals without adding any references outside of version 4 of the framework.

Are there any better patterns I can use that don’t require outside references that accomplish my goal?


tl;dr:

Are there any patterns that satisfy the requirement:

“I need to signal a collection that I am ready for the next element, and have the collection execute a callback when that next element has arrived, without any threads being blocked.”

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-15T19:53:08+00:00Added an answer on May 15, 2026 at 7:53 pm

    I think I have two possible solutions. I am not particularly satisfied with either, but they do at least provide a reasonable alternative to the APM approach.

    The first does not meet your requirement of no blocking thread, but I think it is rather elegant because you can register callbacks and they will get called in round-robin fashion, but you still have the ability to call Take or TryTake as you normally would for a BlockingCollection. This code forces callbacks to be registered each time an item is requested. That is the signalling mechanism for the collection. The nice thing about this approach is that calls to Take do not get starved as they do in my second solution.

    public class NotifyingBlockingCollection<T> : BlockingCollection<T>
    {
        private Thread m_Notifier;
        private BlockingCollection<Action<T>> m_Callbacks = new BlockingCollection<Action<T>>();
    
        public NotifyingBlockingCollection()
        {
            m_Notifier = new Thread(Notify);
            m_Notifier.IsBackground = true;
            m_Notifier.Start();
        }
    
        private void Notify()
        {
            while (true)
            {
                Action<T> callback = m_Callbacks.Take();
                T item = Take();
                callback.BeginInvoke(item, null, null); // Transfer to the thread pool.
            }
        }
    
        public void RegisterForTake(Action<T> callback)
        {
            m_Callbacks.Add(callback);
        }
    }
    

    The second does meet your requirement of no blocking thread. Notice how it transfers the invocation of the callback to the thread pool. I did this because I am thinking that if it got executed synchronously then the locks would be held longer resulting in the bottlenecking of Add and RegisterForTake. I have looked it over closely and I do not think it can get live locked (both an item and a callback are available, but the callback never gets executed) but you might want to look it over yourself to verify. The only problem here is that a call to Take would get starved as callbacks always take priority.

    public class NotifyingBlockingCollection<T>
    {
        private BlockingCollection<T> m_Items = new BlockingCollection<T>();
        private Queue<Action<T>> m_Callbacks = new Queue<Action<T>>();
    
        public NotifyingBlockingCollection()
        {
        }
    
        public void Add(T item)
        {
            lock (m_Callbacks)
            {
                if (m_Callbacks.Count > 0)
                {
                    Action<T> callback = m_Callbacks.Dequeue();
                    callback.BeginInvoke(item, null, null); // Transfer to the thread pool.
                }
                else
                {
                    m_Items.Add(item);
                }
            }
        }
    
        public T Take()
        {
            return m_Items.Take();
        }
    
        public void RegisterForTake(Action<T> callback)
        {
            lock (m_Callbacks)
            {
                T item;
                if (m_Items.TryTake(out item))
                {
                    callback.BeginInvoke(item, null, null); // Transfer to the thread pool.
                }
                else
                {
                    m_Callbacks.Enqueue(callback);
                }
            }
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

.NET for added new concurrency features under System.Collection.Concurrent and some synchronization classes. Is there
In C# some of default name space such as System.Collections are listed without typing
I'm creating a class named TetraQueue that inherits System.Collections.Generic.Queue class overriding the Dequeue method,
Here is my method that returns an IQueryable of Countries: using System; using System.Collections.Generic;
How does SynchronizedCollection<T> and the concurrent collections in the System.Collections.Concurrent namespace differ from each
Looking at System.Collections.Generic.Dictionary<TKey, TValue> , it clearly implements ICollection<KeyValuePair<TKey, TValue>> , but doesn't have
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace GenericCount { class Program {
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; namespace ConsoleApplication1 { public
The description of System.Collection.Specialized.HybridDictionary is this: Implements IDictionary by using a System.Collections.Specialized.ListDictionary while the
For example: using System; using System.Web; using System.Collections; using System.Web.Services; using System.Web.Services.Protocols; using System.Web.Script.Serialization;

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.