我有c#项目,基本上由以下3个类组成。它应该异步读取本地数据库(sqlite)并继续主进程。虽然它不会抛出任何错误,也不会执行db读取。它只执行主进程while(true) {"Doing Stuff on the Main Thread..."}
中包含的无限循环。似乎主线程没有等待异步进程。提前致谢。
class DatabaseAccessor
{
static void Main(string[] args)
{
var inq = new InquireDatabaseAsync();
inq.DoWork();
while (true)
{
Console.WriteLine("Doing Stuff on the Main Thread...");
}
}
}
public class InquireDatabaseAsync
{
public async Task DoWork()
{
await Task.Run(() =>
{
LongRunningOperation();
});
}
private static async Task LongRunningOperation()
{
Data_connection2 dbobject = new Data_connection2();
SQLiteConnection m_dbConnection = new SQLiteConnection();
m_dbConnection.ConnectionString = dbobject.datalocation2();
m_dbConnection.Open();
string sql = "SELECT * FROM Commands WHERE Id = (SELECT MAX(Id) FROM Commands)";
SQLiteCommand SQLcommand = new SQLiteCommand(sql, m_dbConnection);
var instruct = await ExecuteLoopTaskAsync(SQLcommand);
}
public async static Task<string> ExecuteLoopTaskAsync(SQLiteCommand sqlCommand)
{
while (true)
{
System.Threading.Thread.Sleep(1000);
var reader = sqlCommand.ExecuteReader();
while (reader.Read())
Console.WriteLine("Id: " + reader["Id"] + "\tInstruction: " + reader["Instruction"] + "\tCellular: " + reader["Cellular"] + "\tTimestamp: " + reader["Timestamp"]);
}
return "Finished...";
}
}
class Data_connection2
{
public string datalocation2()
{
String dir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
return "Data Source=" + dir + "\\database9.sqlite";
}
}
答案 0 :(得分:3)
此行返回Task
:
inq.DoWork();
但是Task
对象没有做过任何事情。因此它以异步方式启动任务,消费代码不会阻塞它。如果你想阻止它(在这种情况下你可能会这样做),你可以等待任务:
inq.DoWork().Wait();
虽然内部工作可能比我能解释的更复杂(或者我此时完全掌握),但有效应具有与使用时相同的观察行为:
await inq.DoWork();
但由于封闭方法不是async
,因此您无法使用该语法。
基本上考虑事物应该是&#34;一直异步的范式&#34;。这意味着,在任何给定的异步调用堆栈的顶层,应该存在管理Task
的东西。对于诸如WinForms,WPF,ASP.NET等技术,有内置机制来执行此操作。对于控制台应用程序,您基本上更加简单。 main()
方法 是最高级别,需要管理堆栈下面的Tasks
。
答案 1 :(得分:0)
你可能想做的事情可能是,
static void Main(string[] args)
{
var enquiry = new InquireDatabaseAsync().DoWork();
while (!enquiry.IsCompleted)
{
Console.WriteLine("Doing Stuff on the Main Thread...");
}
// In case there were any exceptions.
enquiry.Wait();
}
答案 2 :(得分:0)
虽然DoWork
在内部等待任务,但它会立即返回给调用者!因此,如果呼叫者想要在继续之前等待任务终止,则必须再次等待。
inq.DoWork().Wait();
答案 3 :(得分:0)
此代码有几个问题。考虑使用以下内容:
using System;
using System.Threading.Tasks;
namespace ConsoleApplication6
{
class DatabaseAccessor
{
static async void Main(string[] args)
{
await Task.Run(() =>
{
InquireDatabaseAsync.LongRunningOperation();
});
}
}
public static class InquireDatabaseAsync
{
public static void LongRunningOperation()
{
Data_connection2 dbobject = new Data_connection2();
SQLiteConnection m_dbConnection = new SQLiteConnection();
m_dbConnection.ConnectionString = dbobject.datalocation2();
m_dbConnection.Open();
string sql = "SELECT * FROM Commands WHERE Id = (SELECT MAX(Id) FROM Commands)";
SQLiteCommand SQLcommand = new SQLiteCommand(sql, m_dbConnection);
while (true)
{
System.Threading.Thread.Sleep(1000);
var reader = sqlCommand.ExecuteReader();
while (reader.Read())
Console.WriteLine("Id: " + reader["Id"] + "\tInstruction: " + reader["Instruction"] + "\tCellular: " + reader["Cellular"] + "\tTimestamp: " + reader["Timestamp"]);
break;
}
Console.WriteLine("Finished.");
}
}
class Data_connection2
{
public string datalocation2()
{
String dir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
return "Data Source=" + dir + "\\database9.sqlite";
}
}
}