C# 不能同时运行任务

C# 不能同时运行任务,c#,async-await,task,task-parallel-library,C#,Async Await,Task,Task Parallel Library,我有一个windows窗体应用程序,在我的开发机器上运行良好。但是,在发布应用程序后,我看到尝试并行运行多个任务的奇怪行为。没有错误,但它没有按预期工作。代码如下: private async void Button1_Click(object sender, EventArgs e) { button1.Enabled = false; try { var watch = Stopwatch.StartNew(); textBox1.Te

我有一个windows窗体应用程序,在我的开发机器上运行良好。但是,在发布应用程序后,我看到尝试并行运行多个任务的奇怪行为。没有错误,但它没有按预期工作。代码如下:

private async void Button1_Click(object sender, EventArgs e)
{
    button1.Enabled = false;
    try
    {
        var watch = Stopwatch.StartNew();
        textBox1.Text = $"Processing...";

        await SyncAppDbAsync();

        watch.Stop();
        var time = watch.ElapsedMilliseconds;
        textBox1.Text = $"End successfully. Minutes: {String.Format("{0:0.00}", (double)(time / 1000) / 60)}";
    }
    catch (Exception ex)
    {
        textBox1.Text = $"Message: {ex.Message}, Source: {ex.Source}, HResult: {ex.InnerException}";
    }

}

public async Task SyncAppDbAsync()
{
    //delete tables rows
    // I block the UI for some seconds because not want to write
    // a record if is not deleted
    Task.WaitAll(
        AgenteApp.RemoveAllAgentiAppAsync(),
        RubricaApp.RemoveAllRubricheAppAsync(),
       ...
    );

    //read data da from database
    var readAgents = Task.Run(Agent.GetAgentAsync);
    var readAddressBooks = Task.Run(AddressBook.GetAddressBookAsync);
    ...

    await Task.WhenAll(
         readAgents,
         readAddressBooks,
         ...
     );

    //save data on sqlite database(myDb.db)
    var addAgenti = Task.Run(async () =>
    {
        var progrIndicator = new Progress<int>(AgentiProgress);
        var agenti = AgenteApp.FillAgentiAppFromCompanyAsync(await readAgents, progrIndicator);
        await AgenteApp.AddAgentiAppAsync(await agenti);
    });
    var addRubriche = Task.Run(async () =>
    {
        var progrIndicator = new Progress<int>(RubricheProgress);
        var rubriche = RubricaApp.FillRubricheAppFromCompanyAsync(await readAddressBooks, progrIndicator);
        await RubricaApp.AddRubricheAppAsync(await rubriche);
    });


    await Task.WhenAll(
      addAgenti,
      addRubriche,
     ...
    );
}
private async void按钮1\u单击(对象发送方,事件参数e)
{
按钮1.启用=错误;
尝试
{
var watch=Stopwatch.StartNew();
textBox1.Text=$“处理…”;
等待SyncAppDbAsync();
看,停;
var时间=watch.elapsedmillisons;
textBox1.Text=$“成功结束。分钟:{String.Format(“{0:0.00}”,(double)(time/1000)/60)}”;
}
捕获(例外情况除外)
{
textBox1.Text=$“消息:{ex.Message},源:{ex.Source},HResult:{ex.InnerException}”;
}
}
公共异步任务SyncAppDbAsync()
{
//删除表行
//我阻塞UI几秒钟,因为我不想写
//如果未删除,则记录将被删除
Task.WaitAll(
agentApp.RemoveAllAgentiAppAsync(),
rubricapp.removeallrubricheapasync(),
...
);
//从数据库中读取数据
var readAgents=Task.Run(Agent.GetAgentAsync);
var readAddressBooks=Task.Run(AddressBook.GetAddressBookAsync);
...
等待任务(
读者,
阅读地址簿,
...
);
//在sqlite数据库(myDb.db)上保存数据
var addAgenti=Task.Run(异步()=>
{
var progrIndicator=新进度(AgentiProgress);
var agenti=AgenteApp.FillAgentiAppFromCompanyAsync(等待readAgents、progrIndicator);
等待代理app.AddAgentiAppAsync(等待代理);
});
var addRubriche=Task.Run(异步()=>
{
var progrIndicator=新进展(RubricheProgress);
var rubriche=rubricapp.fillrubricheapfromcompanysync(等待readAddressBooks、progrIndicator);
wait rubricapp.addrubricheapasync(wait rubriche);
});
等待任务(
阿达根蒂,
阿德鲁布里奇,
...
);
}
该代码中的每个任务都对应于sqlite数据库中的一个表。代码从一个sqlite数据库读取数据,然后写入另一个sqlite数据库

我希望这段代码需要几分钟才能运行。同时,应该更新的每个表都有一个进度条。相反,代码只需几秒钟就可以运行,进度条永远不会更新,数据库表也不会改变。我在末尾的文本框中看到此文本:
end successfully。分钟数:0,02

我能做些什么来理解问题并解决它?同样,这在我的开发机器上正常工作

更新: 对不起大家:代码工作得非常好!我犯了愚蠢的错误 具有sqlite数据库的路径。 我在app.config中硬编码:

我接受关于如何使这条道路充满活力的建议
再次抱歉,在我写这篇文章时,问题中没有足够的信息来评估问题。但我至少可以给出一些策略,帮助您自己找到解决方案:

  • 向代码中添加过多的详细日志记录(您可以稍后删除它)。这将有助于您了解程序运行时发生的情况,并有可能看到出错的地方。如果必须,请在生产环境中运行此功能,但最好:

  • 如果您还没有,那么从您自己的机器中获得一个独立的登台或QA环境(如果您确实需要,请使用本地VM),在那里您可以根据需要在生产之外重现问题。上一步中的日志记录信息可能会对此有所帮助

  • 查找异步代码可能隐藏的异常。确保您正在检查每个操作的结果

  • 删除大部分代码。程序将不完整,但它将按预期运行该不完整部分。继续添加更多完整程序的小块,直到它再次中断。在这一点上,你将(可能)知道问题在哪里。。。虽然这可能是一个种族条件造成的较早的块,但至少你会有一个线索,从哪里开始寻找

  • 展开异步代码并使用传统的同步方法运行所有内容。在尝试添加并行性之前,请确保简单的同步代码在生产环境中工作


  • 当您最终发现这个问题时,请确保您有一个单元测试,它将在将来的问题投入生产之前检测到这个问题,以避免回归。

    调用
    WaitAll
    会阻塞线程,不利于异步。请在所有的时候尝试
    。请参阅
    没有错误
    。那很好。。。但在这种情况下,你必须向我们描述你的行为。如果您不共享观察到的行为是什么,以及它与预期的行为有何不同,那么我们怎么可能帮助调试它呢?代码中不清楚,但是与数据库交互本质上不是线程安全的。例如,除非您专门解决多线程问题,否则使用实体框架会有问题。大多数ORM在线程环境中都很好,几乎所有的DBs都是线程安全的,事实上,这就是使用DBs的主要意义。这只是一个注释,但太长了。