Kotlin 的 GlobalScope (Coroutine) 中的代码无法正常工作

Code inside Kotlin's GlobalScope (Coroutine) is not working properly

我正在尝试制作快速排序算法的可视化工具,算法的功能很好,但是当我将代码放入 GlobalScope 以便我可以使用延迟来可视化事物时,算法的行为有所不同。 这是我的功能....

//Quick Sort Part
private suspend fun partition(arr: MutableList<Button>, low: Int, high: Int): Int {
    //If I comment this job, and run the code the algorithm works
    val job2 = GlobalScope.launch(Dispatchers.Main) {
        var low = low
        var high = high
        var pivot = arr[(low + high) / 2].layoutParams.height
       
        while (low <= high) {
            Log.d(TAG, "partition: $low  $high")
            while (arr[low].layoutParams.height < pivot) {
                low++
            }
            while (arr[high].layoutParams.height > pivot) {
                high--
            }

            if (low <= high) {
                val temp = arr[low].layoutParams.height
                arr[low].layoutParams.height = arr[high].layoutParams.height
                arr[high].layoutParams.height = temp
                root_layout.requestLayout()
                low++
                high--
            }
        }
    }
    job2.join()
    return low
}


private fun quickSort(arr: MutableList<Button>, low: Int, high: Int) {
    val job1 = GlobalScope.launch(Dispatchers.Main) {
        val pi = partition(arr, low, high)
        if (low < pi - 1) {
            quickSort(arr, low, pi - 1)
        }
        if (pi < high) {
            quickSort(arr, pi, high)
        }
    }

}

这是该函数的结果,如果我不使用协同程序,它工作正常,所有条形图都按升序排序..

因为您已经在启动范围内定义了 low 和 high 变量,并在那里更新它但仍然返回作为参数接收的变量。

在outerscope中定义它:

var low = low  // define the variable in the outer scope
val job2 = GlobalScope.launch(Dispatchers.Main) {  // ...

但是隐藏不是最好的方法(它很容易出错,因为它欺骗了你),为了简单起见,只是给它起一个别的名字。

提示:主线程的使用通常用于 CPU 强度较低的任务,应该主要用于显示内容和更新 UI。对于计算任务,请随意使用 Dispatchers.Default!

使用 Jobs 来完成任务并加入它们并没有比 withContext 优化得更好,后者旨在轻松地从另一个 Dispatching 线程返回结果,请改用它!

private suspend fun partition(arr: MutableList<Button>, low: Int, high: Int): Int {
    return withContext(Dispatchers.Default) {
        var low = low
        var high = high
        var pivot = arr[(low + high) / 2].layoutParams.height
       
        while (low <= high) {
            Log.d(TAG, "partition: $low  $high")
            while (arr[low].layoutParams.height < pivot) {
                low++
            }
            while (arr[high].layoutParams.height > pivot) {
                high--
            }

            if (low <= high) {
                val temp = arr[low].layoutParams.height
                arr[low].layoutParams.height = arr[high].layoutParams.height
                arr[high].layoutParams.height = temp
                root_layout.requestLayout()
                low++
                high--
            }
        }
        low  //^withContext
    }
}