How to run an expensive sorting as "async" with a coroutine

I have a large list that needs sorting and looping and I want to do that as an “async” run. I know coroutines are not running on a magic thread, but basically continues where it left off the previous frame after it hit a yield return null.

I have messed around with the below coroutine but can’t really nail it down. It keeps freezing the frame.
My thinking is that I set a value and then run the functions, as long as the function is not finished, it ill not return any values and as long as hey haven’t returned anything the IF statements will be false and yield return null.

Obviously it doesn’t work, what am I doing wrong?
Am I still trying to do it on a magic thread?

private IEnumerator SortCoroutine()
{
        var sortedList = SortList(unSortedList);

        if (sortedList == null)
        {
            yield return null;
         }

        bool success = false;
        success = LoopIt(sortedList);

        if (!success)
        {
            yield return null;
        }

       //Done
}

private List<Something> SortList(List<Something> (unsortedList){
       // An expensive sorting
       return sortedList;
}

private bool LoopIt(sortedList){      
             // An expensive loop
}

Ok, so I ended up using an async method instead as I also wanted to return a value, which coroutines doesn’t seem to be able to do according to a UNITE video.

Here’s my solution.

public async void ButtonClick(){
    await SortAsync();
}

private async Task SortAsync()
{
     Debug.Log("Loading...");

     List<Something> sortedList = null;
     sortedList = await Task.Run(() => SortList(unSortedList));
     
     await Task.Run(() => LoopIt(sortedList));

     Debug.Log("Done loading!");
 }

 private List<Something> SortList(List<Something> unsortedList){
    // Sorting algorithm
    return sortedList;
 }

 private void LoopIt(List<ContentItem> sortedList){
    // An expensive loop
 }