Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.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#_Multithreading_Parallel Processing_Async Await_Dispatcher - Fatal编程技术网

C# 调度程序、异步/等待、并发工作

C# 调度程序、异步/等待、并发工作,c#,multithreading,parallel-processing,async-await,dispatcher,C#,Multithreading,Parallel Processing,Async Await,Dispatcher,我有很多异步方法,我从Dispatcher调用它们。这些方法不在后台执行任何工作,它们只是等待一些I/O操作,或者等待来自Web服务器的响应 async Task FetchAsync() { // Prepare request in UI thread var response = await new WebClient().DownloadDataTaskAsync(); // Process response in UI thread } 现在,我想通过调用多个

我有很多异步方法,我从Dispatcher调用它们。这些方法不在后台执行任何工作,它们只是等待一些I/O操作,或者等待来自Web服务器的响应

async Task FetchAsync()
{
    // Prepare request in UI thread
    var response = await new WebClient().DownloadDataTaskAsync();
    // Process response in UI thread
}
现在,我想通过调用多个
FetchAsync()
,以最大程度的并行性来执行负载测试

我的第一次尝试是使用
Paralell.Foreach()
,但是id不能很好地使用async/await

var option = new ParallelOptions {MaxDegreeOfParallelism = 10};
Parallel.ForEach(UnitsOfWork, uow => uow.FetchAsync().Wait());
我一直在研究反应式扩展,但仍然无法利用Dispatcher和async/await

var option = new ParallelOptions {MaxDegreeOfParallelism = 10};
Parallel.ForEach(UnitsOfWork, uow => uow.FetchAsync().Wait());

我的目标是不为每个
FetchAsync()
创建单独的线程。你能给我一些提示吗?

只需调用
Fetchasync
,而不必等待每次调用,然后使用
Task.whalll
一起等待它们

var tasks = new List<Task>();
var max = 10;
for(int i = 0; i < max; i++)
{
    tasks.Add(FetchAsync());
}

await Task.WhenAll(tasks);
var tasks=newlist();
var max=10;
对于(int i=0;i
只需调用
Fetchasync
,而不必等待每次调用,然后使用
Task.whalll
一起等待所有调用

var tasks = new List<Task>();
var max = 10;
for(int i = 0; i < max; i++)
{
    tasks.Add(FetchAsync());
}

await Task.WhenAll(tasks);
var tasks=newlist();
var max=10;
对于(int i=0;i
这是一个通用的可重用解决方案,您不仅可以对FetchAsync方法重用,还可以对具有相同签名的任何异步方法重用。api还包括实时并发节流支持:

参数是不言自明的: totalRequestCount:是要执行的异步请求(FatchAsync调用)总数,异步处理器是FetchAsync方法本身,maxDegreeOfParallelism是可选的可为空参数。如果您希望使用最大并发异步请求数进行实时并发节流,请设置它,否则不设置

public static Task ForEachAsync(
        int totalRequestCount,
        Func<Task> asyncProcessor,
        int? maxDegreeOfParallelism = null)
    {
        IEnumerable<Task> tasks;

        if (maxDegreeOfParallelism != null)
        {
            SemaphoreSlim throttler = new SemaphoreSlim(maxDegreeOfParallelism.Value, maxDegreeOfParallelism.Value);

            tasks = Enumerable.Range(0, totalRequestCount).Select(async requestNumber =>
            {
                await throttler.WaitAsync();
                try
                {
                    await asyncProcessor().ConfigureAwait(false);
                }
                finally
                {
                    throttler.Release();
                }
            });
        }
        else
        {
            tasks = Enumerable.Range(0, totalRequestCount).Select(requestNumber => asyncProcessor());
        }

        return Task.WhenAll(tasks);
    }
公共静态任务ForEachAsync(
int totalRequestCount,
Func异步处理器,
int?maxDegreeOfParallelism=null)
{
i数不清的任务;
if(maxDegreeOfParallelism!=null)
{
SemaphoreSlim throttler=新的信号量lim(maxDegreeOfParallelism.Value,maxDegreeOfParallelism.Value);
tasks=可枚举。范围(0,totalRequestCount)。选择(async requestNumber=>
{
wait throttler.WaitAsync();
尝试
{
await asyncProcessor().ConfigureAwait(false);
}
最后
{
节流器释放();
}
});
}
其他的
{
tasks=Enumerable.Range(0,totalRequestCount)。选择(requestNumber=>asyncProcessor());
}
返回任务。WhenAll(任务);
}

这是一个通用的可重用解决方案,您不仅可以对FetchAsync方法重用,还可以对具有相同签名的任何异步方法重用。api还包括实时并发节流支持:

参数是不言自明的: totalRequestCount:是要执行的异步请求(FatchAsync调用)总数,异步处理器是FetchAsync方法本身,maxDegreeOfParallelism是可选的可为空参数。如果您希望使用最大并发异步请求数进行实时并发节流,请设置它,否则不设置

public static Task ForEachAsync(
        int totalRequestCount,
        Func<Task> asyncProcessor,
        int? maxDegreeOfParallelism = null)
    {
        IEnumerable<Task> tasks;

        if (maxDegreeOfParallelism != null)
        {
            SemaphoreSlim throttler = new SemaphoreSlim(maxDegreeOfParallelism.Value, maxDegreeOfParallelism.Value);

            tasks = Enumerable.Range(0, totalRequestCount).Select(async requestNumber =>
            {
                await throttler.WaitAsync();
                try
                {
                    await asyncProcessor().ConfigureAwait(false);
                }
                finally
                {
                    throttler.Release();
                }
            });
        }
        else
        {
            tasks = Enumerable.Range(0, totalRequestCount).Select(requestNumber => asyncProcessor());
        }

        return Task.WhenAll(tasks);
    }
公共静态任务ForEachAsync(
int totalRequestCount,
Func异步处理器,
int?maxDegreeOfParallelism=null)
{
i数不清的任务;
if(maxDegreeOfParallelism!=null)
{
SemaphoreSlim throttler=新的信号量lim(maxDegreeOfParallelism.Value,maxDegreeOfParallelism.Value);
tasks=可枚举。范围(0,totalRequestCount)。选择(async requestNumber=>
{
wait throttler.WaitAsync();
尝试
{
await asyncProcessor().ConfigureAwait(false);
}
最后
{
节流器释放();
}
});
}
其他的
{
tasks=Enumerable.Range(0,totalRequestCount)。选择(requestNumber=>asyncProcessor());
}
返回任务。WhenAll(任务);
}

不要将
Parallel.ForEach
async/await
混用,因为您已经发现,没有单独的线程,您无法并行运行。看看@AntP:你删除了我的编辑,因为“不需要用asnwers编辑问题”,但在我的编辑中,是对答案的重要修改。请把它滚回去@Liero如果它的不同程度足以成为一个单独的答案,那么它应该作为一个单独的答案发布(而不是在问题内部)。不过,从我所看到的情况来看,这是一个非常狭隘的变化,只适用于这个特定的示例,对于未来的读者来说,这不会是一个重要的区别。不要将
Parallel.ForEach
async/await
混用,因为您已经发现,如果没有单独的线程,您无法并行运行。看看@AntP:你删除了我的编辑,因为“不需要用asnwers编辑问题”,但在我的编辑中,是对答案的重要修改。请把它滚回去@Liero如果它的不同程度足以成为一个单独的答案,那么它应该作为一个单独的答案发布(而不是在问题内部)。不过,从我所看到的情况来看,这是一个非常狭隘的变化,只适用于这个特定的示例,对于未来的读者来说,这不会是一个重要的区别。当我执行
等待任务时。whalll()
,那么在UI线程中仍然会调用FetchAsync?@Liero FetchAsync是在调用FetchAsync时调用的,而不是在等待时调用的,但这就是细节。好的,现在我需要添加MaxDegreeOfParallelism等价物:)当然我可以使用Task.WhenAny()手动实现一些逻辑,但是没有什么东西可以帮助我构建它吗?记住:在这种情况下没有线程。等待UI操作与ha一起工作