简体   繁体   English

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

[英]C# Using Async to run function in separate thread while continuing down main class

I am trying to create an application for learning purposes going along with an Async in C# book. 我正在尝试创建一个用于学习目的的应用程序与C#中的Async一起使用。 However I am having trouble implementing the ideas in the form of which i want. 但是,我无法以我想要的形式实现这些想法。 Please let me know if this is doable or not. 如果这是可行的,请告诉我。

Basically, I have a console application with 3 classes. 基本上,我有一个包含3个类的控制台应用程序。 The user inputs some data on the console and then I have a class which executes a SQL command/query and creates a datatable. 用户在控制台上输入一些数据,然后我有一个执行SQL命令/查询并创建数据表的类。 However the queries actually take quite a bit of time depending on the time of day so this is what I Want: I want to run the class/function which executes my sql query, executes some code right below it in the main program, and then wait for the sql query/data table to finish. 然而,查询实际上需要相当多的时间,具体取决于一天中的时间,所以这就是我想要的:我想运行执行我的sql查询的类/函数,在主程序中执行它下面的一些代码,然后等待sql查询/数据表完成。 After this I then do an export to excel. 在此之后,我然后导出excel。 A portion of the code is below, but what I am having trouble with is the syntax for the async command. 代码的一部分在下面,但我遇到的麻烦是async命令的语法。 I tried making a task which indicates the calling of the sql query function but i get a compiler error saying it cannot convert the type into a task. 我尝试创建一个任务,指示调用sql查询函数,但我得到一个编译器错误,说它无法将类型转换为任务。 Is there a way to do this by assigning my createReport function as a task and then awaiting for it to complete later on? 有没有办法通过将我的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? */ 



          }

You could do this by making your work run in the background and awaiting the results, ie: 您可以通过让您的工作在后台运行并等待结果来完成此操作,即:

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

// Do other work

var report = await task;

That being said, this will only work if the CreateReport method is fine working on a background thread. 话虽这么说,这只有在CreateReport方法在后台线程上工作正常时才有效。

Also - be aware that async in a console application often behaves oddly, as there is no synchronization context to post back onto. 另外 - 请注意,控制台应用程序中的异步通常表现得很奇怪,因为没有同步上下文可以回发。 This means that special care needs to be taken if you want to guarantee that things work properly. 这意味着如果您想保证一切正常,需要特别小心。 A simple way to handle this is to not use async/await, but instead just wait on the result: 处理此问题的一种简单方法是不使用async / await,而只是等待结果:

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

// Do other work

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

The first thing i would advise you is to look if your ORM provider (Entity Franework, ADO.NET, etc) provides an async endpoint. 我建议你的第一件事是看你的ORM提供者(实体Franework,ADO.NET等)是否提供异步端点。 If it does, you wont be needing the extra thread creation, as database work is primarily IO bound. 如果是这样,您将不需要额外的线程创建,因为数据库工作主要是IO绑定。

If it doesn't and you to execute this on a different thread, you may use the Task Parallel Librarys Task class to execute work on a ThreadPool thread: 如果没有,并且您在另一个线程上执行此操作,则可以使用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;
}

Note that when using this in a Console Application you have to make sure your Main method doesn't return, hence terminating you process. 请注意,在控制台应用程序中使用它时,您必须确保您的Main方法不会返回,从而终止您的进程。

I strongly advise you to look for true asynchronous endpoints, those which dont require using a new thread at all. 我强烈建议你寻找真正的异步端点,那些根本不需要使用新线程的端点。

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

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