У меня есть сервер, который принимает несколько клиентских запросов в виде нескольких задач, которые нужно читать и записывать из файла базы данных Microsoft Access .mdb. Я полагал, что у меня будут операции по очереди сервера, когда они вызывают EnqueueWriteCommand и EnqueueReadCommand в качестве задач, а затем у меня будет другая отдельно запущенная задача (ExecuteTasks), запускающая поставленные в очередь задачи. Эта идея кажется безумно запутанной, но я не могу найти или найти лучший способ сделать это. Вот мой код ниже.
По результатам моего тестирования у меня возникает тупик в ExecuteTasks при вызове «await Task.Run (() => task)».
Что вызывает этот тупик? Правильна ли моя общая идея в решении этой проблемы с несколькими потоками? Есть ли лучший способ сделать это?
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;
}
}
}