繁体   English   中英

Win 8.1上的sqlite WinRT线程问题-Windows Phone 8正常运行

[英]sqlite WinRT threading issue on Win 8.1 - Windows Phone 8 works fine

我正在使用Win 8.1应用程序,但在使用最新的sqlite winrt版本时遇到了一些麻烦。 以下代码在Windows Phone 8上可以正常运行,但在Win 8.1上可以冻结。

Database testDB = new Database(ApplicationData.Current.LocalFolder, databaseName);
await testDB.OpenAsync();

Debug.WriteLine("Step 1");

String query = "SELECT * FROM MyTable";
await testDB.PrepareStatementAsync(query);

Debug.WriteLine("Step 2");

Task<Statement> statementTask = testDB.PrepareStatementAsync(query).AsTask();
statementTask.Wait();  // <-- freezes on Win 8.1

Debug.WriteLine("Step 3");

尽管此代码在Windows Phone 8上运行没有任何问题,但在等待statementTask时在Windows 8.1上冻结了。

我知道使用.AsTask()和.Wait()似乎没有多大意义。 但这只是一个示例,在实际项目中,同步运行查询是有意义的。

但是,我想了解问题所在。 为什么在WP而不是Win 8.1上可以使用此功能?

如果我将第二条语句包装到任务中,它也将在Win 8.1上顺利完成:

Task task = Task.Run(() => {
   Task<Statement> statementTask = testDB.PrepareStatementAsync(query).AsTask();
   statementTask.Wait();
 });
task.Wait();

当然,这种实现也没有太大意义。 但是为什么这一个工作而另一个失败呢?

谢谢!

每当阻塞异步任务时(尤其是您没有为其编写代码的异步任务),都将面临死锁的风险。 我将在我的博客MSDN文章中对此进行完整的解释。 总之,可能发生的情况是Win8版本的PrepareStatementAsync是使用await实现的,而没有ConfigureAwait(false) ; 这意味着,如果它在UI线程上启动,则必须在UI线程上恢复。 如果您阻塞UI线程(使用Wait ),那么它将无法在UI线程上继续执行,从而导致死锁。

如果WP8项目使用ConfigureAwait(false) (或完全使用另一种形式的异步实现),则不会死锁。 另外,您的Task.Run示例也Task.Run运行,因为它不是在UI线程上启动(它是在后台线程上启动)。

最好的解决方案是重新评估以下语句:

在实际项目中,同步运行查询是有意义的。

该陈述很可能是错误的。 特别是,由于您正在谈论Win8项目的UI线程,因此几乎绝对是错误的。 最好的解决方案是异步使用API​​,因为它们被设计为可以使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM