Monday, April 26, 2010

C# Improve Responsiveness in Real Time Searching

When you have real-time searching (searching as you type) you will inevitably get a performance hit because each letter you type will trigger a search which usually retrieves data from the database or at best a cache.

One solution is to add a delay and not search until the user has stopped searching for say 500ms.

//declare the timer
private Timer _searchQueueTimer;

...

//Initialize the timer in the constructor
_searchQueueTimer = new Timer();
_searchQueueTimer.Interval = 10;
_searchQueueTimer.Enabled = true;
_searchQueueTimer.Tick += new EventHandler(_searchQueueTimer_Tick);

...

/// 
/// Add the search string to a Queue
/// 
private string _currentSearchItem;
private string _queuedSearchItem;
private DateTime _queuedSearchTime;
public void Search(string search)
{
    if (search.Trim().Length > 0)
    {
        _queuedSearchTime = DateTime.Now;
        _currentSearchItem = search.Trim();
        _queuedSearchItem = _currentSearchItem;
    }
}

/// 
/// Delay the search while user is still typing 
/// before performing the actual search
/// 
private void _searchQueueTimer_Tick(object sender, EventArgs e)
{
    // Time in milliseconds to wait before initiating the search
    const int queueTime = 500;
    if (_queuedSearchItem != null 
     && DateTime.Now.Subtract(_queuedSearchTime).TotalMilliseconds >= queueTime)
        {
            Cursor = Cursors.WaitCursor;//Provide feedback to users
            DoSearch();
            Cursor = Cursors.Default;
        }
}

/// Some psudo code for the method which actually does the search
/// Removes the queued search text from the queue
private Results DoSearch()
{
      if (string.IsNullOrEmpty(_queuedSearchItem))
          return list;

      _queuedSearchItem = null;
      SearchDB();

      return results;
}