我正在尝试使用 MySqlConnector连接到在MariaDB上运行的数据库。但是,如果我从指定的网站执行基本代码段,则一旦异步打开数据库连接(通过调试确定),我的程序就会终止。通常,控制台窗口只是在屏幕上弹出,然后立即再次关闭。
我通过here通过NuGet程序包管理器安装了MySqlConnector。
异步方法的同步版本可以正常工作,我收到了预期的数据。与另一个数据库的连接也不起作用。
这是我的程序:
datatable
为什么会这样?有什么我想念的吗?也许与服务器端的配置有关?
目标框架:.NET Framework 4.7.1 MySqlConnector版本:0.53.0 MariaDB版本:10.3.14
答案 0 :(得分:4)
您的问题是您不等待方法doSomeStuff
的执行,因此,当它到达第一次等待时,它将控制权返回给主程序,并且由于主程序中没有任何事情要做它返回结束程序。
您在这里有2个选择,
是要运行一个主异步等待Task.delay(-1),首先执行您拥有的方法,由于您正在等待一个永无止境的任务,因此您可以完成工作。
像doSomeStuff()。GetAwaiter()。GetResult()这样调用您的方法。这将等待方法执行所需的操作,然后返回到主线程。为了实现这一点,您应该为异步任务而不是异步void更改方法的签名。 (如果使用的是较早的c#版本,则是最佳选择)
选项3(如果是c#7.1或更高版本,则为最佳选项)
答案 1 :(得分:2)
您最大的问题可能是使用 async void 方法,异步void会发生的情况是,当发生错误时,您的方法会静默地死掉(根据位置崩溃应用程序)并且永远不会告诉您问题出在哪里是
网上有几篇文章解释了这一原理,有关内容位于https://haacked.com/archive/2014/11/11/async-void-methods/
在C#中,异步void方法是对代码的祸害。要了解 为什么,我推荐这篇详细的Stephen Cleary文章,最佳实践 在异步编程中。简而言之,调用时引发的异常 异步void方法的处理方式与等待Task和 将导致进程崩溃。不好的体验。
最近,我发现了避免异步void方法的另一个原因。而 在调查错误时,我注意到应该具有的单元测试 表面上是失败的,因为飞色传递的错误。那是 奇。给出该错误,没有合理的理由使测试通过。
然后我注意到该方法的返回类型是异步void。在 直觉我将其更改为异步任务,它开始失败。哦,啪!
您可以在网上检查其他一些内容,异步void主要用于事件,请尝试将void更改为Task,然后弹出您期望的错误(至少您将有一个起点来确定)找出您的连接失败的原因)
另外,如果您正在异步同步中运行异步,则只需执行Task.Run(() => doSomeStuff()).Result;
如果您无权使用await关键字,这将迫使您的方法以同步方式运行至完整状态
答案 2 :(得分:2)
考虑到您正在使用 .NET Framework 4.7.1 ,您可能需要考虑在项目中强制使用 C#7.1 ,并使用>>> insertCommas(23400344.567)
'23,400,344.567'
。它会产生很多更干净的代码,而不会出现任何难看的async Main()
/ GetResult()
/ Result
/ Sleep
。
例如
Task.Delay
如果遇到编译错误,则可能需要强制执行C#7.1:
因此,根据您的情况,将代码更改为:
class Program
{
// Specify C# 7.1 in the project's Properties.Build.Advanced.Language Version field
// in order to use 'static async Task Main'
static async Task Main(string[] args) // <--- Note the async Task
{
Console.WriteLine("Sleeping for 3 seconds");
// the await prevents the app from exiting prematurely
await Task.Delay(TimeSpan.FromSeconds(3));
}
}
尽管有关static async Task Main(string[] args)
{
await doSomeStuff();
}
public static async Task doSomeStuff() // <--- make it Task so it can be await'ed
{
var connString = "Server=localhost;User ID=root;Password=password;Database=mysql";
using (var conn = new MySqlConnection(connString))
{
await conn.OpenAsync();
using (var cmd = new MySqlCommand("SELECT host FROM mysql.user", conn))
using (var reader = await cmd.ExecuteReaderAsync())
while (await reader.ReadAsync())
Console.WriteLine(reader.GetString(0));
}
Console.WriteLine("Finished!");
Console.ReadKey();
}
的 mahlatse的警告是有根据的,但它不适用于您的特定问题,由于没有,应用程序过早退出等待任务完成,而不是由于 async void
方法抛出异常而导致应用程序过早退出。假设您的同步代码和异步代码之间的唯一区别是async void
,而不是说数据库连接应该不出现故障。