Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winforms C#aync Wait-失去焦点时Gui冻结_Winforms_Sorting_Async Await - Fatal编程技术网

Winforms C#aync Wait-失去焦点时Gui冻结

Winforms C#aync Wait-失去焦点时Gui冻结,winforms,sorting,async-await,Winforms,Sorting,Async Await,我最近决定看看C#5的新的异步/等待特性。出于演示目的,我编写了一个Windows窗体应用程序,允许用户获取一个整数数组,并使用他们选择的排序例程对它们进行排序。除了这个程序之外,我还提供了五个test.dat文件,每个文件都包含从32000个整数开始的未排序数据,每个后续文件的大小都是原来的两倍。程序将文件中的数据读取到一个整型数组中,以备排序 我遇到的问题是GUI冻结,完全没有响应。但是,只有将GUI本身置于后台时,它才会冻结。i、 例如,我看不到它,因为我可能正忙于浏览互联网等。它可能不会

我最近决定看看C#5的新的异步/等待特性。出于演示目的,我编写了一个Windows窗体应用程序,允许用户获取一个整数数组,并使用他们选择的排序例程对它们进行排序。除了这个程序之外,我还提供了五个test.dat文件,每个文件都包含从32000个整数开始的未排序数据,每个后续文件的大小都是原来的两倍。程序将文件中的数据读取到一个整型数组中,以备排序

我遇到的问题是GUI冻结,完全没有响应。但是,只有将GUI本身置于后台时,它才会冻结。i、 例如,我看不到它,因为我可能正忙于浏览互联网等。它可能不会立即冻结。有时我可能会让它重新聚焦,但它仍然会工作,但最终会失败。如果我始终保持程序的焦点,GUI将保持完全响应。我可以在屏幕上拖动它。我可以最小化和最大化它。在结果表单显示经过的排序时间之前,一个字幕样式的进度条会显示动画,我可以继续单击按钮等

现在我想补充一点,我不认为这是排序算法本身的问题。我的理由是,当GUI处于焦点时,它可以正常工作。我还有一套完整的单元测试来验证每种算法是否能够正常工作。运行时间似乎是一个问题,因为堆或快速排序等更快的算法可以处理非常大的数据集,而不会导致冻结。最后,我尝试在表单级别(等待任务)和任务本身捕获异常,但似乎没有抛出异常

在过去的两天里,我刚刚研究了async/await,我并不是一个专家,但我最初的想法是,它可能与购买回focus后的GUI重新绘制有关。有人能帮忙吗?以下是代码的部分,以帮助:-

示例SelectionSort例程:-

public SelectionSort(IStopwatch stopwatch) : base(stopwatch){}

    public override async Task<int[]> SortAsync(int[] data, CancellationToken cancelToken)
    {
        OnStarted();           
        Stopwatch.Start();

        await Task.Run(() =>
            {
                int i, j;
                int min, temp;

                for (i = 0; i < data.Length - 1; i++)
                {
                    if (cancelToken.IsCancellationRequested)
                        return;

                    min = i;
                    for (j = i + 1; j < data.Length; j++)
                    {
                        if (data[j] < data[min])
                            min = j;
                    }
                    temp = data[i];
                    data[i] = data[min];
                    data[min] = temp;
                }
            }, cancelToken);

        Stopwatch.Stop();

        OnCompleted(new SortCompleteEventArgs(Stopwatch.ElapsedMilliseconds, data.Length, cancelToken.IsCancellationRequested));

        return data;
    }

异步代码似乎没有什么问题。当排序后引发OnComplete事件时,主表单中的处理程序将实例化一个新的结果表单并显示它。当窗体失去焦点时,这是失败的。我正在研究为什么会出现这种情况,以及这是否是一个经过深思熟虑的框架设计决策。无论如何,我只是在处理程序中调用了Activate()方法。这使应用程序成为焦点,然后我实例化了新表单,它工作得很好。不管怎样,至少对我来说可以。e、 g:-

private void DisplaySortResults(object sender, SortCompleteEventArgs e)
    {
        Activate();

        _btnCancelSort.Enabled = false;
        _progressBar.Style = ProgressBarStyle.Continuous;

        var sortResults = new SortResults();

        sortResults.BuildResults(e);
        sortResults.SetCompletedValues(e);
        sortResults.ShowDialog();
    }

async
的一个更合适的演示是一个自然的异步操作,即对本地主机服务器的web请求,每个请求都会休眠
async
主要不是为CPU密集型工作而设计的,尽管您可以使用
Task.Run
,就像这里一样。也就是说,我在你发布的代码中没有看到任何会导致UI响应问题的东西。这很奇怪。这似乎取决于排序算法中引发的OnCompleted事件。如果被注释掉了,没有问题,没有冻结,尽管很明显,结果屏幕现在不会显示。在关注gui的情况下,工作再次正常。当它在后台时失败。几乎被难住了,但仍在努力。有一种感觉,这可能是一个“踢我自己”的时刻。有一件事要检查:确保结果不是每个UI元素(例如,100000个列表项不会很好)。嗨,Stephen。谢谢你的意见。结果数据不是以这种方式使用的。我将编辑我的帖子,因为它实际上冻结在较小的排序数字上。请注意,我说的是“现在”,但我怀疑它一直在这样做,不知何故我错过了它。
private async void StartSorting_Click(object sender, EventArgs e)
    {
        if (_lBoxSelectedFiles.Items.Count == 0)
        {
            MessageBox.Show("Select data to sort");
            return;
        }

        _btnCancelSort.Enabled = true;

        if (_comboBxAlgorithm.SelectedValue.Equals("SelectSort"))
        {
            var selectSort = new SelectSort(new SortStopwatch());
            selectSort.Completed += DisplaySortResults;
            _sorter = new SorterContext(selectSort);

            StartProgressBar();

             await _sorter.Sort(_dataToSort, _cancelTokenSrcWrapper.Token);   
        }
private void DisplaySortResults(object sender, SortCompleteEventArgs e)
    {
        Activate();

        _btnCancelSort.Enabled = false;
        _progressBar.Style = ProgressBarStyle.Continuous;

        var sortResults = new SortResults();

        sortResults.BuildResults(e);
        sortResults.SetCompletedValues(e);
        sortResults.ShowDialog();
    }