隐藏

Post并发请求在C#多线程是如何处理实现

发布:2022/12/26 15:01:51作者:管理员 来源:本站 浏览次数:407

需求:如从文件中读取了10条数据,将数据参数循环给post请求,然后分别记录每个请求所用时间,最后记录平均请求时间,希望能从原有代码上使用多线程处理。请求和响应。

原有代码:

//读取excel

ds = Extensions.FilesIO.ExcelRead(file_path, "sheet1");

for (int i = 0; i < 5; i++)

{

id = ds.Tables[0].Rows[i][0].ToString().Trim();

name = ds.Tables[0].Rows[i][1].ToString().Trim();

//请求参数

var par = new Dictionary<string, string>();

par.Add("name", name);

par.Add("id", id);


//测试demo

result = Extensions.Http_Conn.SendPost(url, par, "get");

  记录当前请求时间

}

记录平均时间

1、

    async Task<long> post()
    {
        var stopwatch = new Stopwatch();
        stopwatch.Start();
        var client = new HttpClient();
        await client.GetStringAsync("https://www.baidu.com");
        stopwatch.Stop();
        return stopwatch.ElapsedMilliseconds;
    }
    public async Task<long[]> Exec()
    {
        Task<long>[] tasks = new Task<long>[10];
        for (int i = 0; i < 10; i++)
        {
            tasks[i] = post();
        }
        await Task.WhenAll(tasks);
        return tasks.Select(x => x.Result).ToArray();
    }

2、

private static Dictionary __RetryLocker = new Dictionary(128);
private static object __LockDicLocker = new object();

    private static object GetLocker(string fileKey)
    {
        if (!__RetryLocker.TryGetValue(fileKey, out Object lockObj))
        {
            lock (__LockDicLocker)
            {
                if (__RetryLocker.ContainsKey(fileKey))
                {
                    lockObj = __RetryLocker[fileKey];
                }
                else
                {
                    lockObj = new object();
                    __RetryLocker.Add(fileKey, lockObj);
                }
            }
        }
        return lockObj;
    }
    private static void RemoveLocker(string fileKey)
    {
        lock (__LockDicLocker)
        {
            __RetryLocker.Remove(fileKey);
        }
    }
            // 线种中要执行的方法
    private static void Retry(string messageFile)
    {
        if (!File.Exists(messageFile))
        {
            return;
        }
        string fileKey = Security.MD5Encode(messageFile.ToLower());
        object lockObj = GetLocker(fileKey);
        lock (lockObj)
        {
            if (File.Exists(messageFile))
            {
                SBMessage message = XmlSerializer.DeserializeFromFile<SBMessage>(messageFile);
                                    // 一个远程请求,可以修改为任务要执行的功能。其中可以包括请求时间的记录,可以将请求时间记录到静态变量中。自行处理
                MessagePublisher.Publish(message, msg =>
                {
                    RemoveLocker(fileKey);
                    File.Delete(messageFile);
                });
            }
            else
            {
                RemoveLocker(fileKey);
            }
        }
    }
    public static void Retry()
    {
        string[] files = Directory.GetFiles(MsgCacheFolder, "*.xml");
        if (files != null && files.Length > 0)
        {
            int lastCount = files.Length;
            int page = 20; // 最大线程数量
            List<Task> taskList = new List<Task>(lastCount > page ? page : lastCount);
            for (int i = 0; i < files.Length; i++)
            {
                string tfn = files[i];
                Task task = new Task(() =>
                {
                    string rfn = tfn;
                    Retry(rfn);
                });
                task.Start();
                taskList.Add(task);
                lastCount = files.Length - i - 1;
                if (taskList.Count >= page || lastCount == 0)
                {
                    try
                    {
                        Task.WaitAll(taskList.ToArray());
                    }
                    catch (Exception ex)
                    {
                        MessagePublisher.Log(LogType.Exception, ex.ToString());
                    }
                    taskList = new List<Task>(lastCount > page ? page : lastCount);
                }
            }
            taskList = null;
        }
    }