Search code examples
c#multithreadingsearchcancellationtokensource

Thread cancellation token for direct search bar


I have a datagridview filtered by a search bar. I wanted to reproduce the google like search on keyup.

Since the database might get bigger, I was trying to cancel previous search on next charachter input (it is currently quite fast, so I setup a sleep).

It seems that the canceltoken is not checked everytime between the cancelation order and the new creation. (line 2 and line 5) which seems normal, but anoying for the purpose.

Is there a "Show this to all thread before setting a new one" methods for the said token? Or a way to call an old token? Maybe a list? Set a dictionnary with a datetime?

Any advices on this kind of system would be very welcome.

private CancellationTokenSource cts { get; set; }

      protected async void SearchGrid(object Sender, EventArgs e)
        {
 FullGridView.CurrentCell = null;
            cts = cts ?? new CancellationTokenSource

();
            cts.Cancel();
            List<string> SearchFor = Box.Text.Split(null).ToList();

        cts = new CancellationTokenSource();await Task.Run(() =>
                {
                    try
                    {
                        foreach (DataGridViewRow Row in FullGridView.Rows)
                        {   if ((Row.Cells[0].Value as bool?) == true)
                            { continue; }

                            cts.Token.ThrowIfCancellationRequested();
                            bool Found = false;

                            Found = SearchFor.All(s =>
                            ColumnIndexToSearch.Any(c =>
                            Row.Cells[c].Value != null &&
                            Row.Cells[c].Value.ToString().ToUpperInvariant()
                            .Contains(s.ToUpperInvariant())));
                            SyncCtx.Post(delegate
                            {
                                Row.Visible = Found;
                            }, null);
                            Thread.Sleep(5000); //Test purpose
                        }

                    }
                    catch
                    {
                        return;
                    }
                }, cts.Token);

Solution

  • Finally I created a List<CancellationTokenSource> cts then I cancel Last() then create a new one. It keeps alive the token and avoid the race condition.