Cancel sorting in .NET?

I use ListView in VirtualMode to show a very large number of rows, millions of rows. String data stored in a shared list.

Now I want to implement a sort function that sorts the list by some Comparer.

The problem is that at the moment the average single sort takes about 30 seconds, and during this time the user cannot do anything with the ListView and must wait until it ends.

Not every user agrees to wait so long, most users will cancel the sort if they can, and I want to enable this undo feature. Unfortunately, the built-in List.Sort cannot be undone or Array.Sort.

Sorting is currently in a separate thread, so I can use Thread.Abort, but this trial version will result in a damaged list, which is unacceptable to me.

Is there anything I can do but override the whole Sort algorithm myself?

thanks.

+3
source share
5 answers

Copy the list, sort the copy in the stream, and then replace the original list (if the sorting is completed without interruption).

But I would go with Martignoni’s suggestion, if possible β€” so that millions of lines in the application begin, I feel different. Databases can do much better filtering and sorting of data before they reach you.

+5

. Array.Sort , Thread.Abort . , , ( )

, IAsyncResult, CancelRequested bool. , bool, true , . , . . . , ref, , , . , , .

,

+3

. , BeginXXX/EndXXX CancelXXX. , , , . , .

public class Sorter
{
  public IAsyncResult BeginSort(IList<T> values, AsyncCallback complete)
  {
    MyAsyncResult asyncResult = new MyAsyncResult();
    Thread t = new Thread(() =>
      {
        // Implement your sorting algorithm here.
        // Periodically check asyncResult.Cancel at safe points.
        asyncResult.Complete();
        if (complete != null)
        {
          complete(asyncResult);
        }
      });
    t.Start();
    return asyncResult;
  }

  public void EndSort(IAsyncResult asyncResult)
  {
    MyAsyncResult target = asyncResult as MyAsyncResult;
    if (target == null)
    {
      throw new ArgumentException();
    }
    // Add code here to extract any additional information from the IAsyncResult that 
    // you might want to return to the client. Perhaps this method will be empty.
  }

  public void CancelSort(IAsyncResult asyncResult)
  {
    MyAsyncResult target = asyncResult as MyAsyncResult;
    if (target == null)
    {
      throw new ArgumentException();
    }
    target.Cancel = true;
  }

  private class MyAsyncResult : IAsyncResult
  {
    private volatile bool m_Cancel = false;

    public bool Cancel
    {
      get { return m_Cancel; }
      set { m_Cancel = value; }
    }

    public void Complete()
    {
      // Add code here to mark this IAsyncResult as complete.
    }
  }
}
+2

- , ( ), , , .

+1

, . . , list list.

0

Source: https://habr.com/ru/post/1723561/


All Articles