Синхронизация всего класса к потокам - C#
Формулировка задачи:
Привет!
В моем коде есть 2 потока, первый поток подключается к базе, вот код:
Но есть второй поток, который вызывает MysqlConnector.mysqlclose(), но не может, так как первый поток использует этот класс как подключение и постоянно занимает его собой, как мне синхронизировать весь класс, чтобы первый поток мог вызывать mysqlconnect(), а второй mysqlclose()
Заранее спасибо!
namespace LoginServer.network.mysql.MysqlConnector
{
class MysqlConnector
{
public static MySqlConnection mysqlConnect = null;
public static string Connect;
public static int mysqlconnected;
//Connect to mysql
public static bool mysqlconnect(string server, string user, string database, string port, string password)
{
Connect = "server=" + server + ";user=" + user + ";database=" + database + ";port=" + port + ";password=" + password + ";";
MySqlConnection mysqlConnect = new MySqlConnection(Connect);
try
{
mysqlConnect.Open();
ConsoleUtilities.consoleinfo("SUCCESSFULLY CONNECTED TO DB");
mysqlconnected = 1;
return true;
}
catch (Exception)
{
ConsoleUtilities.consolerror("ERROR WHEN CONNECT TO DB");
return false;
}
}
//Close Mysql Connection
public static bool mysqlclose()
{
try
{
mysqlConnect.Close();
ConsoleUtilities.consoleinfo("DB CLOSED");
return true;
}
catch (Exception)
{
ConsoleUtilities.consolerror("ERROR WHEN CLOSE DB");
return false;
}
}
}
}Решение задачи: «Синхронизация всего класса к потокам»
textual
Листинг программы
using System.Threading;
namespace xcv
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//Семафор 1 - под главный поток, всего - 2
sema = new Semaphore(1, 2);
//Создаем поток для класса конектора
th = new Thread(new ThreadStart(delegate
{
//Для избежания неправильных межпотоковых вызовов
sc = new SynchronizationContext();
//Создаем класс коннектора в отдельном потоке
conn = new Connector();
//Суспендим
Thread.Sleep(Timeout.Infinite);
}));
//Запускаем
th.Start();
}
//поток с конектором
Thread th;
private void button1_Click(object sender, EventArgs e)
{
//Первый поток
((AsyncCallback)delegate
{
while (true)
{
//Занимаем семафор или ждём пока освободиться
sema.WaitOne();
//Обращаемся к коннектору в его потоке
sc.Send(delegate { conn.Connect(); }, null);
//Типа делаем своё дело
Thread.Sleep(1200);
//Дисконектимся
sc.Send(delegate { conn.Disconnect(); }, null);
//Освобождаем Семафор
sema.Release();
}
}).BeginInvoke(null, null, null);
//Второй поток, тут тоже самое что и выше.
((AsyncCallback)delegate
{
while (true)
{
sema.WaitOne();
sc.Send(delegate { conn.Connect(); }, null);
Thread.Sleep(1700);
sc.Send(delegate { conn.Disconnect(); }, null);
sema.Release();
}
}).BeginInvoke(null, null, null);
}
SynchronizationContext sc;
Semaphore sema;
Connector conn;
class Connector
{
bool Connected = false;
public void Connect()
{
//Вот тут критические секцие уже не нужны, потому что семафорим доступ,
//однако если семафоры убрать - будет вылетать ошибка...
Thread.BeginCriticalRegion();
if (Connected) throw new Exception("Double connect!");
Connected = true;
Thread.EndCriticalRegion();
Thread.Sleep(2000);
}
public void Disconnect()
{
Thread.EndCriticalRegion();
if (!Connected) throw new Exception("Double disconnect");
Connected = false;
Thread.EndCriticalRegion();
Thread.Sleep(2500);
}
}
}
}