我有一个服务器,它接受多个客户端请求作为需要从Microsoft Access .mdb数据库文件读取和写入的多个任务。当他们将EnqueueWriteCommand和EnqueueReadCommand作为任务调用时,我想让服务器将它们排队,然后让另一个单独运行的任务(ExecuteTasks)运行排队的任务。这个想法令人费解,但是我似乎找不到或找到更好的方法来做到这一点。这是下面的代码。
从我的测试中,当我调用“ await Task.Run(()=> task)”时,似乎在ExecuteTasks中出现了死锁。
是什么原因导致此僵局?我的总体思路在解决多线程问题时是否正确?有更好的方法吗?
using System.Data.OleDb;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Diagnostics;
namespace appDatabaseConsole
{
/// <summary>
/// Contains all necessary components for initializing and interacting with
the database file.
/// </summary>
public static class DBHandler
{
private static OleDbConnection c;
private static OleDbDataReader reader;
private static OleDbCommand command;
private static List<Task> tasks;
/// <summary>
/// Initialize the connection of the OleDbConnection components to the database file.
/// </summary>d
public static void InitializeConnection()
{
c = new OleDbConnection
{
ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\\AppDatabase.mdb"
};
command = new OleDbCommand
{
Connection = c
};
reader = null;
tasks = new List<Task>();
// Run the Task executor ask a separate task
Task.Run(() => ExecuteTasks());
}
private async static Task ExecuteTasks()
{
while (true)
{
if (tasks.Count > 0)
{
Debug.WriteLine("tasks.Count exceeded zero");
foreach (Task task in tasks)
{
await Task.Run(() => task);
tasks.Remove(task);
Debug.WriteLine("Completed task and removed task.");
}
}
}
}
public static void EnqueueWriteCommand(string commandText)
{
Debug.WriteLine("Start EnqueueWriteCommand");
Task task = new Task(() => WriteCommand(commandText));
tasks.Add(task);
Debug.WriteLine("Finish EnqueueWriteCommand");
}
public static List<string>[] EnqueueReadCommand(string commandText, int numberOfColumns)
{
Debug.WriteLine("Start EnqueueReadCommand");
Task<List<string>[]> task = new Task<List<string>[]>(() => ReadCommand(commandText, numberOfColumns));
tasks.Add(task);
Debug.WriteLine("Just before finishing EnqueueReadCommand");
return task.Result;
}
private static void WriteCommand(string commandText)
{
Debug.WriteLine("Start WriteCommand");
c.Open();
command.CommandText = commandText;
command.ExecuteNonQuery();
c.Close();
Debug.WriteLine("Finish WriteCommand");
}
private static List<string>[] ReadCommand(string commandText, int numberOfColumns)
{
Debug.WriteLine("Start ReadCommand");
c.Open();
command.CommandText = commandText;
reader = command.ExecuteReader();
List<string>[] data = new List<string>[numberOfColumns];
for (int column = 0; column < numberOfColumns; column++)
{
while (reader.Read())
{
data[column].Add(reader[column].ToString());
}
}
reader.Close();
c.Close();
Debug.WriteLine("Finish ReadCommand");
return data;
}
}
}