相关疑难解决方法(0)

等待具有不同结果的多个任务

我有3个任务:

private async Task<Cat> FeedCat() {}
private async Task<House> SellHouse() {}
private async Task<Tesla> BuyCar() {}
Run Code Online (Sandbox Code Playgroud)

他们都需要在我的代码可以继续之前运行,我也需要每个代码的结果.结果没有任何共同之处

如何调用并等待3个任务完成然后获得结果?

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

205
推荐指数
7
解决办法
8万
查看次数

我想等待抛出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万
查看次数

验证正在等待任务

我有以下代码,我想测试:

private Task _keepAliveTask; // get's assigned by object initializer

public async Task EndSession()
{
    _cancellationTokenSource.Cancel(); // cancels the _keepAliveTask
    await _logOutCommand.LogOutIfPossible();
    await _keepAliveTask;
}
Run Code Online (Sandbox Code Playgroud)

重要的是,EndSession只有`_keepAliveTask'结束后,Task才会结束.但是,我很难找到一种方法来可靠地测试它.

问题:我如何对EndSession方法进行单元测试并验证等待Task返回的方法.EndSession_keepAliveTask

出于演示目的,单元测试可能如下所示:

public async Task EndSession_MustWaitForKeepAliveTaskToEnd()
{
    var keepAliveTask = new Mock<Task>();
    // for simplicity sake i slightly differ from the other examples
    // by passing the task as method parameter

    await EndSession(keepAliveTask);

    keepAliveTask.VerifyAwaited(); // this is what i want to achieve
}
Run Code Online (Sandbox Code Playgroud)

进一步的标准: - …

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

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

在示例代码中是否需要Task.WhenAll?

在下面的代码中,task1和task2彼此独立,可以并行运行.以下两个实现有什么区别?

var task1 = GetList1Async();
var task2 = GetList2Async();

await Task.WhenAll(task1, task2);

var result1 = await task1; 
var result2 = await task2; 
Run Code Online (Sandbox Code Playgroud)

var task1 = GetList1Async();
var task2 = GetList2Async();

var result1 = await task1; 
var result2 = await task2; 
Run Code Online (Sandbox Code Playgroud)

我为什么要选择一个而不是另一个?

编辑:我想补充一点,返回类型的GetList1Async()和GetList2Async()方法是不同的.

c# task-parallel-library async-await

7
推荐指数
1
解决办法
7391
查看次数

并发执行异步方法

使用async/await模型,我有一个方法,它对Web服务进行3次不同的调用,然后返回结果的并集.

var result1 = await myService.GetData(source1);
var result2 = await myService.GetData(source2);
var result3 = await myService.GetData(source3);

allResults = Union(result1, result2, result3);
Run Code Online (Sandbox Code Playgroud)

使用典型等待,这3个调用将彼此同步执行.我将如何让它们同时执行并在完成后加入结果?

c# async-await

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

ASP .Net Core 排队后台任务并行处理

我有一个 ASP .NET core Web API,它使用此处描述的排队后台任务 。

我已使用提供的代码示例并添加了IBackgroundTaskQueue,BackgroundTaskQueue和 ,QueuedHostedService完全按照文章中所述。

在 my 中Startup.cs,我仅注册一个QueuedHostedService实例,如下所示:services.AddHostedService<QueuedHostedService>();

来自 WebApi 控制器的任务将被入队,然后出队并由QueuedHostedService.

我希望允许多个后台处理线程使传入的任务出队并执行。我能想到的最直接的解决方案是QueuedHostedService在我的Startup.cs. 即,像这样:

 int maxNumOfParallelOperations;
 var isValid = int.TryParse(Configuration["App:MaxNumOfParallelOperations"], out maxNumOfParallelOperations);

 maxNumOfParallelOperations = isValid && maxNumOfParallelOperations > 0 ? maxNumOfParallelOperations : 2;

 for (int index = 0; index < maxNumOfParallelOperations; index++) 
 {
    services.AddHostedService<QueuedHostedService>();
 }
Run Code Online (Sandbox Code Playgroud)

我还注意到,由于 中的信号量BackgroundTaskQueueQueuedHostedService实例并不是一直在工作,而是仅在队列中有新任务可用时才唤醒。

这个解决方案在我的测试中似乎效果很好。

但是,在这个特定的用例中 - 它真的是一个有效的、推荐的并行处理解决方案吗?

c# asp.net parallel-processing asp.net-core asp.net-core-hosted-services

5
推荐指数
1
解决办法
6670
查看次数

以适当的方式在异步方法中连续三个任务的结果

我是异步编程的新手.我很想知道这些任务是否可以同时运行.考虑我有这个代码:

public async Task<IList<WebData>> GetAllAsync()
{
    var twitterData = await ProvidetwitterDataAsync();
    var facebookData = await ProvidefacebookDataAsync();
    var linkedinData = await ProvidelinkedinDataAsync();
    return twitterData .Concat(facebookData ).Concat(linkedinData ).ToList();
}
Run Code Online (Sandbox Code Playgroud)

我想因为我用过await twitterData那个Task应该完成,然后下一个Task将开始,因为我想连续这三个列表的结果我用这种方式编写它,我想知道有没有办法可以同时完成这三个任务?这种实施方式是正确的还是有更好的方法?

c# task async-await

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

Task.WhenAll in async方法,然后解开每个任务

我有两个可以并行运行的任务来提高性能:

var task1 = _service.DoStuffAsync();
var task2 = _service.DoOtherStuffAsync();

await Task.WhenAll(task1, task2);
Run Code Online (Sandbox Code Playgroud)

现在,我确信这些任务已经完成.但根据我的理解(以及一些现实生活中的麻烦),如果我呼吁.Result完成这些任务,即使它们完整,我也可能造成僵局?

从我正在阅读的内容来看,await完成的任务只会返回结果,所以看起来就是这样的方式.这使我的代码看起来很时髦:

var task1 = _service.DoStuffAsync();
var task2 = _service.DoOtherStuffAsync();

await Task.WhenAll(task1, task2);

var result1 = await task1;
var result2 = await task2;
Run Code Online (Sandbox Code Playgroud)

这是解决此问题并获得我的任务结果的正确方法吗?如果没有,问题是什么?有没有更好的方法来打开任务而不需要.Result它们?

c# task async-await

2
推荐指数
1
解决办法
452
查看次数

使用无限while循环防止高CPU使用率的正确方法(控制台/表单混合)

我把一个控制台/表单混合程序放在一起,为了实现我正在寻找的行为,我必须在一个线程中"运行"控制台,然后用另一个启动仪表板.

我用过BackgroundWorker这个.基本上在Main方法中我启动控制台后台工作器,它在其DoWork块中执行正常的while循环以保持控制台运行.重复检查来自控制台的输入并将其传递给它相应的操作.

while (true && !Program.Shutdown)
{
    String consoleInput = "";

    consoleInput = Program.ReadFromConsole();

    if (String.IsNullOrWhiteSpace(consoleInput))
        continue;

    try
    {
        Program.Shell(consoleInput);
    }
    catch (Exception ex)
    {
        Program.WriteToConsole(ex.Message);
    }
}
Run Code Online (Sandbox Code Playgroud)

在调用启动控制台的后台工作程序之后,即ConsoleBackgroundWorker.RunWorkerAsync()调用执行加载序列的方法.

此加载序列CAN调用第二个后台工作程序,该工作程序在单独的线程内部启动仪表板.

现在我遇到的问题是加载序列结束时的循环.此循环可防止所有事务都关闭,直到两个后台工作程序都已完成(窗体关闭或控制台发送命令关闭)

while (ConsoleBackgroundWorker != null && DashboardBackgroundWorker != null)
{
    /* I'm not sure of how else to fix this. But 
     * this corrects the high CPU usage reported 
     * in the Task Manager. */
    System.Threading.Thread.Sleep(10);
}
Run Code Online (Sandbox Code Playgroud)

问题是CPU使用率,它一直保持在30%,这是没有你上面看到的那条线 System.Threading.Thread.Sleep(10)

我的问题是,这样可以吗?如果没有,我有什么解决方案?我注意到这确实纠正了这个问题,当应用程序没有做任何事情时,CPU现在的速度为0%.我也没有看到任何性能变化.但它还没有真正被"推",所以我不能肯定地说后者的观察.

.net c# multithreading

0
推荐指数
1
解决办法
3255
查看次数