为什么调用“ OpenAsync()”时我的程序被终止?

时间:2019-05-10 12:04:06

标签: c# mysql asynchronous ado.net mysql-connector

我正在尝试使用 MySqlConnector连接到在MariaDB上运行的数据库。但是,如果我从指定的网站执行基本代码段,则一旦异步打开数据库连接(通过调试确定),我的程序就会终止。通常,控制台窗口只是在屏幕上弹出,然后立即再次关闭。

我通过here通过NuGet程序包管理器安装了MySqlConnector。

异步方法的同步版本可以正常工作,我收到了预期的数据。与另一个数据库的连接也不起作用。

这是我的程序:

datatable

为什么会这样?有什么我想念的吗?也许与服务器端的配置有关?

目标框架:.NET Framework 4.7.1 MySqlConnector版本:0.53.0 MariaDB版本:10.3.14

3 个答案:

答案 0 :(得分:4)

您的问题是您不等待方法doSomeStuff的执行,因此,当它到达第一次等待时,它将控制权返回给主程序,并且由于主程序中没有任何事情要做它返回结束程序。

您在这里有2个选择,

  1. 是要运行一个主异步等待Task.delay(-1),首先执行您拥有的方法,由于您正在等待一个永无止境的任务,因此您可以完成工作。

  2. 像doSomeStuff()。GetAwaiter()。GetResult()这样调用您的方法。这将等待方法执行所需的操作,然后返回到主线程。为了实现这一点,您应该为异步任务而不是异步void更改方法的签名。 (如果使用的是较早的c#版本,则是最佳选择)

  3. MickyD的
  4. 选项3(如果是c#7.1或更高版本,则为最佳选项)

  

https://stackoverflow.com/a/56078498/10513564

答案 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:

enter image description here

因此,根据您的情况,将代码更改为:

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,而不是说数据库连接应该出现故障。