Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.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
C# 信号量包装方法_C#_Async Await_Task_Semaphore - Fatal编程技术网

C# 信号量包装方法

C# 信号量包装方法,c#,async-await,task,semaphore,C#,Async Await,Task,Semaphore,基于这样的一些问题,主要是这个问题: 我已经实现了SemaphoreSlim对象,以便在我的应用程序中通过一系列方法并发处理请求。这些方法中的大多数都是接收ID列表,并以并发方式从web上获取每个ID的单字节数组。实现如下所示: using (var semaphore = new SemaphoreSlim(MaxConcurrency)) { var tasks = fileMetadata.GroupBy(x =&

基于这样的一些问题,主要是这个问题:

我已经实现了SemaphoreSlim对象,以便在我的应用程序中通过一系列方法并发处理请求。这些方法中的大多数都是接收ID列表,并以并发方式从web上获取每个ID的单字节数组。实现如下所示:

 using (var semaphore = new SemaphoreSlim(MaxConcurrency))
                {
                    var tasks = fileMetadata.GroupBy(x => x.StorageType).Select(async storageTypeFileMetadata=>
                    {
                        await semaphore.WaitAsync();
                        try
                        {
                            var fileManager = FileManagerFactory.CreateFileManager((StorageType)storageTypeFileMetadata.Key);
                            await fileManager.UpdateFilesAsync(storageTypeFileMetadata);
                        }
                        finally
                        {
                            semaphore.Release();
                        }
                    });

                    await Task.WhenAll(tasks);
                }
有没有一种方法可以为信号量代码抽象出一个方法或一些可重用的代码片段,并传入我需要完成的工作,这样就可以重用它而无需每次重新编写信号量代码?使用相同信号量模式的多个方法之间的唯一区别是我正在迭代的列表以及它在try{}中所做的工作


我的想法类似于pass list。选择(x=>my task method,其中包含我的工作)到一个信号量方法,它是所有包装器信号量代码。

所以我猜测类似于:

public static class Extension
{
    public static async Task ExecuteAsync<T>(this IEnumerable<T> items, Func<T, Task> task, int concurrency)
    {
        var tasks = new List<Task>();

        using (var semaphore = new SemaphoreSlim(concurrency))
        {
            foreach (var item in items)
            {
                tasks.Add(ExecuteInSemaphore(semaphore, task, item));
            }

            await Task.WhenAll(tasks);
        }
    }

    private static async Task ExecuteInSemaphore<T>(SemaphoreSlim semaphore, Func<T, Task> task, T item)
    {
        await semaphore.WaitAsync();

        try
        {
            await task(item);
        }
        finally
        {
            semaphore.Release();
        }
    }
}

所以,为了在开发时节省一些击键,您愿意在运行时进行委托实例化和调用。是吗?主要原因首先是出于好奇,其次是可能没有20多个方法包装在完全相同的代码中,这使得可读性更加困难,因为该方法的主要功能是2行。仍在测试这一点,但看起来需要在lambda.ExecuteAsync之前添加async(async storageTypeFileMetadata=>@mameesh,仅当您等待其中的内容时。在我给出的示例中,这不是必需的
await fileMetadata.GroupBy(x => x.StorageType).ExecuteAsync(storageTypeFileMetadata =>
{
    var fileManager = FileManagerFactory.CreateFileManager((StorageType)storageTypeFileMetadata.Key);
    return fileManager.UpdateFilesAsync(storageTypeFileMetadata);
}, 4);