相关疑难解决方法(0)

异步并等待For循环

我有一个Windows服务,根据计划运行各种作业.确定要运行的作业后,会将一个计划对象列表发送到迭代列表并运行每个作业的方法.问题是由于外部数据库调用,某些作业最多可能需要10分钟才能运行.

我的目标是没有一个工作阻止其他队列,基本上一次有多个运行.我认为使用async和await可以解决这个问题,但我以前从未使用过这些.

现行代码:

public static bool Load(List<Schedule> scheduleList)
{
    foreach (Schedule schedule in scheduleList)
    {
        Load(schedule.ScheduleId);
    }

    return true;
}

public static bool Load(int scheduleId)
{
    // make database and other external resource calls 
    // some jobs run for up to 10 minutes   

    return true;
}
Run Code Online (Sandbox Code Playgroud)

我尝试更新到这段代码:

public async static Task<bool> LoadAsync(List<Schedule> scheduleList)
{
    foreach (Schedule schedule in scheduleList)
    {
        bool result = await LoadAsync((int)schedule.JobId, schedule.ScheduleId);
    }

    return true;
}

public async static Task<bool> LoadAsync(int scheduleId)
{
    // make database …
Run Code Online (Sandbox Code Playgroud)

.net c# multithreading asynchronous async-await

22
推荐指数
1
解决办法
3万
查看次数

如何使用异步方法正确编写Parallel.For

我将如何构造下面的代码,以便调用异步方法?

Parallel.For(0, elevations.Count(), delegate(int i)
{
   allSheets.AddRange(await BuildSheetsAsync(userID, elevations[i], includeLabels));
});
Run Code Online (Sandbox Code Playgroud)

.net c# task-parallel-library async-await

19
推荐指数
2
解决办法
2万
查看次数

并行运行异步方法

我有一个异步方法,GetExpensiveThing()它执行一些昂贵的I/O工作.这就是我使用它的方式:

// Serial execution
public async Task<List<Thing>> GetThings()
{
    var first = await GetExpensiveThing();
    var second = await GetExpensiveThing();
    return new List<Thing>() { first, second };
}
Run Code Online (Sandbox Code Playgroud)

但由于这是一种昂贵的方法,我想并行执行这些调用.我本以为移动等待会解决这个问题:

// Serial execution
public async Task<List<Thing>> GetThings()
{
    var first = GetExpensiveThing();
    var second = GetExpensiveThing();
    return new List<Thing>() { await first, await second };
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,所以我将它们包装在一些任务中,这有效:

// Parallel execution
public async Task<List<Thing>> GetThings()
{
    var first = Task.Run(() =>
    {
        return GetExpensiveThing();
    });

    var second = Task.Run(() =>
    { …
Run Code Online (Sandbox Code Playgroud)

c# task-parallel-library async-await

17
推荐指数
2
解决办法
2万
查看次数

你如何使用asParallel与async和await关键字?

我正在查看异步的某个示例代码,并注意到它实现方式的一些问题.在查看代码时,我想知道使用并行循环遍历列表是否更有效,而不是正常循环遍历列表.

据我所知,性能差异很小,两者都占用了每个处理器,两者都在相同的时间内完成.

这是第一种方式

var tasks= Client.GetClients().Select(async p => await p.Initialize());
Run Code Online (Sandbox Code Playgroud)

这是第二个

var tasks = Client.GetClients().AsParallel().Select(async p => await p.Initialize());
Run Code Online (Sandbox Code Playgroud)

假设两者之间没有区别,我是否正确?

完整的程序可以在下面找到

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

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            RunCode1();
            Console.WriteLine("Here");
            Console.ReadLine();

            RunCode2();
            Console.WriteLine("Here");

            Console.ReadLine();

        }

        private async static void RunCode1()
        {
            Stopwatch myStopWatch = new Stopwatch();
            myStopWatch.Start();

            var tasks= Client.GetClients().Select(async p => await p.Initialize());

            Task.WaitAll(tasks.ToArray());
            Console.WriteLine("Time ellapsed(ms): " + myStopWatch.ElapsedMilliseconds);
            myStopWatch.Stop();
        }
        private async …
Run Code Online (Sandbox Code Playgroud)

c# asynchronous

16
推荐指数
2
解决办法
7776
查看次数

我想等待抛出AggregateException,而不仅仅是第一个Exception

等待故障任务(具有异常集的任务)时,await将重新抛出存储的异常.如果存储的异常是a AggregateException,它将重新抛出第一个并丢弃其余的异常.

我们如何使用await并同时抛出原件AggregateException以便我们不会意外丢失错误信息?

注意,当然可以考虑使用hacky解决方案(例如,试一试await,然后调用Task.Wait).我真的希望找到一个干净的解决方案.这里最好的做法是什么?

我想过使用自定义awaiter,但内置TaskAwaiter包含很多魔法,我不知道如何完全重现.它调用TPL类型的内部API.我也不想重现所有这些.

如果你想玩它,这是一个简短的repro:

static void Main()
{
    Run().Wait();
}

static async Task Run()
{
    Task[] tasks = new[] { CreateTask("ex1"), CreateTask("ex2") };
    await Task.WhenAll(tasks);
}

static Task CreateTask(string message)
{
    return Task.Factory.StartNew(() => { throw new Exception(message); });
}
Run Code Online (Sandbox Code Playgroud)

只抛出两个例外中的一个Run.

请注意,Stack Overflow上的其他问题无法解决此特定问题.建议重复时请小心.

c# task-parallel-library async-await c#-5.0

16
推荐指数
3
解决办法
1万
查看次数

IO绑定操作的并行执行

我已阅读TPL和任务库文档封面.但是,我仍然无法清楚地理解以下案例,现在我需要实施它.

我会简化我的情况.我IEnumerable<Uri>的长度是1000.我必须使用它来请求它们HttpClient.

我有两个问题.

  1. 没有太多的计算,只是在等待HTTP请求.在这种情况下我还可以使用Parallel.Foreach()吗?
  2. 在使用的情况下,Task创建大量的最佳实践是什么?假设我使用Task.Factory.StartNew()并将这些任务添加到列表中并等待所有这些任务.是否有一个功能(如TPL分区程序)控制最大任务的数量和HttpClient我可以创建的最大值?

在SO上有几个类似的问题,但没有人提到最大值.该要求仅使用具有最大HttpClient的最大任务.

先感谢您.

c# task task-parallel-library

14
推荐指数
2
解决办法
5330
查看次数

在Parallel.foreach中等待

我有一个将在Parallel.Foreach中使用的异步方法.在异步方法中有等待任务.但是,在测试中,似乎没有等待行为,await Task没有完成.有什么问题?下面是代码.

public void method1()
{
  Ilist<string> testList = new IList<string>(){"1","2","3"};
  Parallel.ForEach(testList, ()=>
  {
       method2();
  });
}
public async void method2()
{
   await Task.run(()=>{  some other codes here });  
}
Run Code Online (Sandbox Code Playgroud)

c# task-parallel-library async-await parallel.foreach

9
推荐指数
2
解决办法
2万
查看次数

如何正确地并行运行多个异步任务?

如果您需要并行运行多个异步I/O任务但需要确保不会同时运行多个XI/O进程,该怎么办?I/O处理前后的任务不应该有这样的限制.

这是一个场景 - 假设有1000个任务; 每个人都接受一个文本字符串作为输入参数; 转换该文本(预I/O处理)然后将转换后的文本写入文件.目标是使预处理逻辑利用100%的CPU /内核和任务的I/O部分以最大10度并行性运行(同时打开最多10个用于一次写入文件).

你能提供一个示例代码如何使用C#/ .NET 4.5吗?

http://blogs.msdn.com/b/csharpfaq/archive/2012/01/23/using-async-for-file-access-alan-berman.aspx

c# asynchronous task-parallel-library async-await async-ctp

8
推荐指数
1
解决办法
3851
查看次数

重载I/O操作中的Parallel.ForEach与Async Forloop

我想比较两种理论情景.为了这个问题,我简化了案例.但基本上它是典型的生产者消费者情景.(我专注于消费者).

我有一个很大的Queue<string> dataQueue,我必须传输到多个客户端.

所以让我们从更简单的情况开始:

 class SequentialBlockingCase
 {
    public static Queue<string> DataQueue = new Queue<string>();
    private static List<string> _destinations = new List<string>();

    /// <summary>
    /// Is the main function that is run in its own thread
    /// </summary>
    private static void Run()
    {
        while (true)
        {
            if (DataQueue.Count > 0)
            {
                string data = DataQueue.Dequeue();
                foreach (var destination in _destinations)
                {
                    SendDataToDestination(destination, data);
                }
            }
            else
            {
                Thread.Sleep(1);
            }
        }
    }

    private static void SendDataToDestination(string destination, string data)
    { …
Run Code Online (Sandbox Code Playgroud)

c# multithreading task-parallel-library async-await

7
推荐指数
2
解决办法
2355
查看次数

确定 C# Partitioner.GetPartitions() 的 partitionCount 的因素

下面是Stephen Toub 编写的一个实现ForEachAsync

public static Task ForEachAsync<T>(this IEnumerable<T> source, int dop, Func<T, Task> body) 
{ 
    return Task.WhenAll( 
        from partition in Partitioner.Create(source).GetPartitions(dop) 
        select Task.Run(async delegate { 
            using (partition) 
                while (partition.MoveNext()) 
                    await body(partition.Current); 
        })); 
}
Run Code Online (Sandbox Code Playgroud)

指定 partitionCount 时应考虑哪些因素(dop在本例中)?

硬件是否有所作为(内核数量、可用 RAM 等)?

数据/操作的类型是否影响计数?

我的第一个猜测是在一般情况下设置为dop等于Environment.ProcessorCount,但我的直觉告诉我这可能无关。

c# asynchronous task-parallel-library async-await

6
推荐指数
1
解决办法
704
查看次数