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

  • SEARCH
  • Home
  • 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 6571451
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T14:53:03+00:00 2026-05-25T14:53:03+00:00

I have a search application that takes some time (10 to 15 seconds) to

  • 0

I have a search application that takes some time (10 to 15 seconds) to return results for some requests. It’s not uncommon to have multiple concurrent requests for the same information. As it stands, I have to process those independently, which makes for quite a bit of unnecessary processing.

I’ve come up with a design that should allow me to avoid the unnecessary processing, but there’s one lingering problem.

Each request has a key that identifies the data being requested. I maintain a dictionary of requests, keyed by the request key. The request object has some state information and a WaitHandle that is used to wait on the results.

When a client calls my Search method, the code checks the dictionary to see if a request already exists for that key. If so, the client just waits on the WaitHandle. If no request exists, I create one, add it to the dictionary, and issue an asynchronous call to get the information. Again, the code waits on the event.

When the asynchronous process has obtained the results, it updates the request object, removes the request from the dictionary, and then signals the event.

This all works great. Except I don’t know when to dispose of the request object. That is, since I don’t know when the last client is using it, I can’t call Dispose on it. I have to wait for the garbage collector to come along and clean up.

Here’s the code:

class SearchRequest: IDisposable
{
    public readonly string RequestKey;
    public string Results { get; set; }
    public ManualResetEvent WaitEvent { get; private set; }

    public SearchRequest(string key)
    {
        RequestKey = key;
        WaitEvent = new ManualResetEvent(false);
    }

    public void Dispose()
    {
        WaitEvent.Dispose();
        GC.SuppressFinalize(this);
    }
}

ConcurrentDictionary<string, SearchRequest> Requests = new ConcurrentDictionary<string, SearchRequest>();

string Search(string key)
{
    SearchRequest req;
    bool addedNew = false;
    req = Requests.GetOrAdd(key, (s) =>
        {
            // Create a new request.
            var r = new SearchRequest(s);
            Console.WriteLine("Added new request with key {0}", key);
            addedNew = true;
            return r;
        });

    if (addedNew)
    {
        // A new request was created.
        // Start a search.
        ThreadPool.QueueUserWorkItem((obj) =>
            {
                // Get the results
                req.Results = DoSearch(req.RequestKey);  // DoSearch takes several seconds

                // Remove the request from the pending list
                SearchRequest trash;
                Requests.TryRemove(req.RequestKey, out trash);

                // And signal that the request is finished
                req.WaitEvent.Set();
            });
    }

    Console.WriteLine("Waiting for results from request with key {0}", key);
    req.WaitEvent.WaitOne();
    return req.Results;
}

Basically, I don’t know when the last client will be released. No matter how I slice it here, I have a race condition. Consider:

  1. Thread A Creates a new request, starts Thread 2, and waits on the wait handle.
  2. Thread B Begins processing the request.
  3. Thread C detects that there’s a pending request, and then gets swapped out.
  4. Thread B Completes the request, removes the item from the dictionary, and sets the event.
  5. Thread A’s wait is satisfied, and it returns the result.
  6. Thread C wakes up, calls WaitOne, is released, and returns the result.

If I use some kind of reference counting so that the “last” client calls Dispose, then the object would be disposed by Thread A in the above scenario. Thread C would then die when it tried to wait on the disposed WaitHandle.

The only way I can see to fix this is to use a reference counting scheme and protect access to the dictionary with a lock (in which case using ConcurrentDictionary is pointless) so that a lookup is always accompanied by an increment of the reference count. Whereas that would work, it seems like an ugly hack.

Another solution would be to ditch the WaitHandle and use an event-like mechanism with callbacks. But that, too, would require me to protect the lookups with a lock, and I have the added complication of dealing with an event or a naked multicast delegate. That seems like a hack, too.

This probably isn’t a problem currently, because this application doesn’t yet get enough traffic for those abandoned handles to add up before the next GC pass comes and cleans them up. And maybe it won’t ever be a problem? It worries me, though, that I’m leaving them to be cleaned up by the GC when I should be calling Dispose to get rid of them.

Ideas? Is this a potential problem? If so, do you have a clean solution?

  • 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-25T14:53:04+00:00Added an answer on May 25, 2026 at 2:53 pm

    Consider using Lazy<T> for SearchRequest.Results maybe? But that would probably entail a bit of redesign. Haven’t thought this out completely.

    But what would probably be almost a drop-in replacement for your use case is to implement your own Wait() and Set() methods in SearchRequest. Something like:

    object _resultLock;
    
    void Wait()
    {
      lock(_resultLock)
      {
         while (!_hasResult)
           Monitor.Wait(_resultLock);
      }
    }
    
    void Set(string results)
    {
      lock(_resultLock)
      {
         Results = results;
         _hasResult = true;
         Monitor.PulseAll(_resultLock);
      }
    }
    

    No need to dispose. 🙂

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a web application that allows a user to search on some criteria,
I have a web application that allows users to enter search criteria and the
In my jsp application I have a search box that lets user to search
In android how to search that sharedpreference contains some value or not? Actually I
I have a search screen in my WPF application. The screen is implemented as
I have implemented solr search for my rails application. I have indexed the fields
I suddenly have Run and Search in the menubar of my RCP application. Is
I am working on Android Application. Now I have requirement of search the entered
I am trying use gem tire to search in my application. I have tables
I have an application implementing incremental search. I have a catalog of unicode strings

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.