简体   繁体   English

报错Argument 2: cannot convert from 'System.Threading.Tasks.ParallelLoopState' to 'System.Threading.CancellationToken' 如何解决?

[英]Getting error Argument 2: cannot convert from 'System.Threading.Tasks.ParallelLoopState' to 'System.Threading.CancellationToken' how to solve?

Following on:接下来:

How to download files using HttpClient with a ProgressBar?如何使用带有 ProgressBar 的 HttpClient 下载文件?

The project is WinForms .NET 6项目是WinForms .NET 6

How to solve the erro:如何解决错误:

Severity Code Description Project File Line Suppression State Error CS1503 Argument 2: cannot convert from 'System.Threading.Tasks.ParallelLoopState' to 'System.Threading.CancellationToken' WinFormsApp1 D:\Csharp\WinFormsApp1\ResourceDownloader.cs 63 Active严重性代码说明项目文件行抑制 State 错误 CS1503 参数 2:无法从“System.Threading.Tasks.ParallelLoopState”转换为“System.Threading.CancellationToken”WinFormsApp1 D:\Csharp\WinFormsApp1\ResourceDownloader.cs 63 活动

On line number 63第 63 行

var dataBytes = await client.Value.GetByteArrayAsync(site, token);

The full class code:完整的 class 代码:

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace WinFormsApp1
{
    public class ResourceDownloader
    {
        private static Lazy<HttpClient> client = new(() => {
            HttpClientHandler handler = CreateHandler(autoRedirect: true);

            var client = new HttpClient(handler, true) { Timeout = TimeSpan.FromSeconds(60) };
            client.DefaultRequestHeaders.Add("User-Agent", @"Mozilla/5.0 (Windows NT 10; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0");
            client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
            client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
            client.DefaultRequestHeaders.ConnectionClose = true;
            return client;
        }, true);

        private static HttpClientHandler CreateHandler(bool autoRedirect)
        {
            return new HttpClientHandler()
            {
                AllowAutoRedirect = autoRedirect,
                CookieContainer = new CookieContainer(),
                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
            };
        }

        public record Website(string Url, byte[]? Data, bool Completed = true, Exception? Ex = null);
        public record ProgressReport(Website Site, int PercentageComplete);

        private static object syncObj = new object();
        private static ConcurrentBag<Website> processed = default!;
        private static int progressCount = 0;
        private static int totalCount = 0;

        public static bool IsBusy { get; internal set; } = false;

        public static async Task<List<Website>> Download(IProgress<ProgressReport> progress, IList<string> sites, CancellationTokenSource cts)
        {
            IsBusy = true;
            processed = new ConcurrentBag<Website>();
            progressCount = 0;
            totalCount = sites.Count;

            try
            {
                ParallelOptions options = new()
                {
                    MaxDegreeOfParallelism = 8,
                    CancellationToken = cts.Token
                };

                await Parallel.ForEach(sites, options, async (site, token) => {
                    try
                    {
                        var dataBytes = await client.Value.GetByteArrayAsync(site, token);
                        ReportProgress(progress, dataBytes, site, null);
                    }
                    catch (Exception ex)
                    {
                        ReportProgress(progress, null, site, ex);
                    }
                });
            }
            // To Debug / Log
            catch (TaskCanceledException) { Debug.Print("The operation was canceled"); }
            finally { IsBusy = false; }
            return processed.ToList();
        }

        private static void ReportProgress(IProgress<ProgressReport> progress, byte[]? data, string site, Exception? ex)
        {
            lock (syncObj)
            {
                progressCount += 1;
                var percentage = progressCount * 100 / totalCount;
                Website website = new(site, data, ex is null, ex);
                processed.Add(website);
                progress.Report(new ProgressReport(website, percentage));
            }
        }
    }
}

Parallel.ForEach is not Task -aware and does not handle asynchronous workloads (correctly, at least), and overloads accepting handler with 2 parameters (like ForEach<TSource>(IEnumerable<TSource>, Action<TSource,ParallelLoopState>) ) use ParallelLoopState as second parameter of the handler. Parallel.ForEach不是Task感知的并且不处理异步工作负载(至少正确地),并且重载接受具有 2 个参数的处理程序(如ForEach<TSource>(IEnumerable<TSource>, Action<TSource,ParallelLoopState>) )使用ParallelLoopState作为处理程序的第二个参数。

You need to use Parallel.ForEachAsync (for example this overload , which accepts Func<TSource, CancellationToken, ValueTask> ) to correctly handle async workloads.您需要使用Parallel.ForEachAsync (例如这个 overload ,它接受Func<TSource, CancellationToken, ValueTask> )来正确处理异步工作负载。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 'System.Threading.CancellationToken'...未标记为可序列化 - 'System.Threading.CancellationToken'...is not marked as serializable System.NotSupportedException:&#39;不支持在基于任务的异步方法上使用&#39;System.Threading.CancellationToken&#39;。&#39; - System.NotSupportedException: 'The use of 'System.Threading.CancellationToken' on the task-based asynchronous method is not supported.' 参数1:无法从“ System.Threading.Tasks.Task”转换 <Project.Models.Booking> &#39;到Project.Models.Booking - Argument 1: cannot convert from 'System.Threading.Tasks.Task<Project.Models.Booking>' to Project.Models.Booking 无法将 System.Threading.Task.Tasks 转换为 System.Func <system.func<system.threading.tasks.task></system.func<system.threading.tasks.task> - Cannot convert System.Threading.Task.Tasks to System.Func<System.Func<System.Threading.Tasks.Task> 无法从“ System.Threading.Tasks.Task”转换为“ System.Collections.Generic.Dictionary” <string,string> &#39; - Cannot convert from 'System.Threading.Tasks.Task' to 'System.Collections.Generic.Dictionary<string,string>' 无法从“无效”转换为System.Threading.Tasks.Task <System.Action> - Cannot convert from 'void' to System.Threading.Tasks.Task<System.Action> 无法将类型&#39;void&#39;隐式转换为&#39;System.Threading.Tasks.Task&#39; - Cannot implicitly convert type 'void' to 'System.Threading.Tasks.Task' 无法隐式转换类型&#39;System.Threading.Tasks.Task - Cannot implicitly convert type 'System.Threading.Tasks.Task 无法将类型&#39;bool&#39;隐式转换为&#39;System.Threading.Tasks.Task&#39; - Cannot implicitly convert type 'bool' to 'System.Threading.Tasks.Task' 有时我在System.Threading.Tasks.TaskCompletionSource上不断获取异常 <bool> 我该如何解决? - I keep getting exception sometimes on System.Threading.Tasks.TaskCompletionSource<bool> how can i solve it?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM