我正在尝试使用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? */
}
答案 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
方法不会返回,从而终止您的处理。
我强烈建议你寻找真正的异步端点,那些根本不需要使用新线程的端点。