【发布时间】:2019-09-23 23:05:09
【问题描述】:
我有一个在我的开发机器上运行良好的 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,
...
);
}
该代码中的每个任务对应于 sqlite 数据库中的一个表。该代码从一个 sqlite 数据库读取数据并写入另一个 sqlite 数据库。
我预计这段代码需要几分钟才能运行。同时,每个应该更新的表都有一个进度条。相反,代码只运行了几秒钟,进度条永远不会更新,数据库表也没有改变。我在最后的文本框中看到此文本:End successfully. Minutes: 0,02。
我可以做些什么来了解问题并解决它?同样,这在我的开发机器上也能正常工作。
更新: 对不起大家:代码工作得很好!我犯了愚蠢的错误 带有sqlite数据库的路径。 我在 app.config 中硬编码:
我接受有关如何使该路径动态化的建议 所以再次抱歉
【问题讨论】:
-
WaitAll调用阻塞了线程,不利于异步。请改用WhenAll。见stackoverflow.com/questions/6123406/waitall-vs-whenall -
There is no error。没关系……但在那种情况下,你必须向我们描述行为。如果您不分享观察到的行为是什么,以及它与预期有何不同,我们怎么可能帮助调试? -
从您的代码中不清楚,但与数据库交互本质上不是线程安全的。例如,除非您专门解决多线程问题,否则使用实体框架会出现问题。
-
这是 EF 中的一个问题,而不是 DBs @BurnsBA 。大多数 ORM 在线程环境中都很好,几乎所有数据库都是线程安全的,事实上这几乎就是使用数据库的重点
标签: c# async-await task task-parallel-library