C#使用Async在继续关闭主类的同时在单独的线程中运行函数

时间:2014-08-01 19:04:19

标签: c# multithreading asynchronous task async-await

我正在尝试使用C#中的Async创建一个用于学习目的的应用程序。但是,我无法以我想要的形式实现这些想法。如果这是可行的,请告诉我。

基本上,我有一个包含3个类的控制台应用程序。用户在控制台上输入一些数据,然后我有一个执行SQL命令/查询并创建数据表的类。然而,查询实际上需要相当多的时间,具体取决于一天中的时间,所以这就是我想要的:我想运行执行我的sql查询的类/函数,在主程序中执行它下面的一些代码,然后等待sql查询/数据表完成。在此之后,我然后导出excel。代码的一部分在下面,但我遇到的麻烦是async命令的语法。我尝试创建一个任务,指示调用sql查询函数,但我得到一个编译器错误,说它无法将类型转换为任务。有没有办法通过将我的createReport函数指定为任务然后等待它稍后完成来完成此操作?

 if (Regex.IsMatch(Number,@"^\d+$") && Number.Length <= 3)
        {

      reportCreate.createReport(detailLength,detailDate,detailNumber);

   /* ^^ This was my original syntax but I want to make this asynchronous or in 
   a separate thread so I can continue working below.*/ 

   // do some comparing work here while the sql query/datatable is running.

   /* Wait for the datatable thread to finish and then continue with the code 
    below. Is there a way to do this using task and await? */ 



          }

2 个答案:

答案 0 :(得分:2)

您可以通过让您的工作在后台运行并等待结果来完成此操作,即:

var task = Task.Run(()=>reportCreate.CreateReport(...));

// Do other work

var report = await task;

话虽如此,只有在CreateReport方法在后台线程上正常工作时才会有效。

另外 - 请注意,控制台应用程序中的异步通常表现得很奇怪,因为没有同步上下文可以回发。这意味着如果您想保证一切正常,需要特别小心。处理此问题的一种简单方法是不使用async / await,而只是等待结果:

var task = Task.Run(()=>reportCreate.CreateReport(...));

// Do other work

var report = task.Result; // Will block until first task is done

答案 1 :(得分:1)

我建议您首先看看您的ORM提供程序(Entity Franework,ADO.NET等)是否提供异步端点。如果是这样,您将不需要额外的线程创建,因为数据库工作主要是IO绑定。

如果它没有并且你在另一个线程上执行它,你可以使用Task Parallel Librarys Task类来执行ThreadPool线程的工作:

if (Regex.IsMatch(Number,@"^\d+$") && Number.Length <= 3)
{
    var createReportTask = Task.Run(() => { reportCreate.createReport(detailLength,detailDate,detailNumber }));

    // do some comparing work here while the sql query/datatable is running.

    await createReportTask;
}

请注意,在控制台应用程序中使用此功能时,您必须确保Main方法不会返回,从而终止您的处理。

我强烈建议你寻找真正的异步端点,那些根本不需要使用新线程的端点。