获得异步任务功能漫长的过程进展

问题描述 投票:-1回答:1

我有一个异步函数和所使用的进展<int>的

我再跑任务后进步漫长的过程,似乎许多进度报告正在运行。

private async void Listbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var progress = new Progress<int>(percent =>
                    {
                        prg.Value = percent;
                    });
    isCanceled = true;
    await ExecuteManuallyCancellableTaskAsync(progress);

}

这是我的FUNC

public async Task ExecuteManuallyCancellableTaskAsync(IProgress<int> progress)
{
    var mprogress = 0;
    prg.Value = 0;
    using (var cancellationTokenSource = new CancellationTokenSource())
    {
        cancellationTokenSource.Cancel();

        var SearchTask = Task.Run(async () =>
        {
            foreach (var file in await GetFileListAsync(GlobalData.Config.DataPath))
            {
                if (isCanceled)
                {
                    cancellationTokenSource.Cancel();
                    return;
                }
                mprogress += 1;
                progress.Report((mprogress * 100 / TotalItem));

                await Dispatcher.InvokeAsync(() =>
                {
                    // my codes
                }, DispatcherPriority.Background);
            }
        });

        await SearchTask;
    }
}

这是结果,你可以看到进度条同一时间不同的值。 enter image description here

c# wpf asynchronous async-await progress
1个回答
2
投票

总之你没有正确使用CancellationTokenSource有2个原因;首先,它需要到处传递给您,才能真正取消这些调用任何async方法,其次可能需要住的不仅仅是你在哪里使用它的范围内较长。

尝试这样的事情(完整的意见,希望可以很容易地遵循):

private CancellationTokenSource cancellationTokenSource; // And remove isCanceled as this is causing some of the issues
private async void Listbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var progress = new Progress<int>(percent =>
                    {
                        prg.Value = percent;
                    });

    // Make sure any current processing is stopped.
    cancellationTokenSource?.Cancel();

    // Prepare to be able to cancel the next round of processing.
    cancellationTokenSource = new CancellationTokenSource();

    await ExecuteManuallyCancellableTaskAsync(progress, cancellationTokenSource.Token);
}
public async Task ExecuteManuallyCancellableTaskAsync(IProgress<int> progress, CancellationToken cancelToken)
{
    var mprogress = 0;
    prg.Value = 0;

    await Task.Run(async () =>
    {
        // You will need to implement checks against the CancellationToken in your GetFileListAsync method also.
        foreach (var file in await GetFileListAsync(GlobalData.Config.DataPath, cancelToken))
        {
            mprogress += 1;
            progress.Report((mprogress * 100 / TotalItem));

            // Only update the UI if we have not been requested to cancel.
            if (!cancelToken.IsCancellationRequested)
            {
                await Dispatcher.InvokeAsync(() =>
                {
                    // my codes
                }, DispatcherPriority.Background);
            }
        }
    }, cancelToken); // Pass in the token to allow the Task to be cancelled.
}
© www.soinside.com 2019 - 2024. All rights reserved.