#delphi
#delphi
Вопрос:
У меня есть класс, в котором есть внутренняя очередь и объект подключения к серверу. Когда элемент помещается в очередь, создается соединение, и элемент обрабатывается, соединение уничтожается, а затем цикл ожидает следующего элемента в очереди.
Я хочу, чтобы после создания соединения сохранялось созданное в течение X секунд / минут, в случае нажатия какого-либо нового элемента мне не нужно заново создавать и повторно аутентифицировать соединение. Вот пример:
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, System.Classes, System.Generics.Collections, System.Threading;
type
TConn = class
public
procedure Authenticate;
end;
TMyClass = class
private
FQueue: TThreadedQueue<TProc<TConn>>;
FTask: ITask;
procedure Start;
public
constructor Create;
destructor Destroy; override;
procedure Push(Proc: TProc<TConn>);
end;
{ TConn }
procedure TConn.Authenticate;
begin
end;
{ TMyClass }
constructor TMyClass.Create;
begin
FQueue := TThreadedQueue<TProc<TConn>>.Create;
Start;
end;
destructor TMyClass.Destroy;
begin
FQueue.DoShutDown;
FQueue.Free;
inherited;
end;
procedure TMyClass.Push(Proc: TProc<TConn>);
begin
FQueue.PushItem(Proc);
end;
procedure TMyClass.Start;
var
Proc: TProc<TConn>;
Conn: TConn;
begin
FTask := TTask.Run(procedure
begin
while not FQueue.Shutdown or (FQueue.QueueSize > 0) do
begin
//Blocked by internal TMonitor, released when DoShutdown is called or PushItem
FQueue.PopItem(Proc);
if FQueue.ShutDown then
Exit;
Conn := TConn.Create;
Conn.Authenticate;
Proc(Conn);
Conn.Free;
end;
end);
end;
var
MyClass: TMyClass;
begin
try
MyClass := TMyClass.Create;
MyClass.Push(procedure(AParam: TConn)
begin
//use conn
end);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
При вызове Conn.Free
я хочу подождать и оставить его созданным на некоторое время. Если истечет время ожидания X секунд / минут, соединение будет уничтожено и воссоздано в следующем элементе.
Является ли таймер лучшим подходом здесь? Я не люблю использовать таймеры, но в данном случае, я думаю, это имеет смысл.
Я мог бы использовать тайм-аут TThreadedQueue, но тайм-аут устанавливается при создании объекта и используется при ожидании PopItem
. Я хотел дождаться только создания соединения, если соединения нет, нет смысла использовать этот тайм-аут. Если бы тайм-аут TThreadedQueue был доступен в prop, я мог бы установить его при создании conn, а затем, после уничтожения, вернуться к бесконечности. Но это не так.
Есть предложения?
Комментарии:
1. В таких ситуациях часто используется объединение пулов соединений. Отдельный поток поддерживает активные соединения и управляет пулом. Другие потоки получают и возвращают соединения в пул по мере необходимости.
2. В этом случае соединение осуществляется с сервером приложений. На сервере есть пул подключений к базе данных. Здесь, в клиенте, у меня есть только одно соединение с сервером. Существует соединение по умолчанию (используемое основным потоком), я хочу реализовать это второе фоновое соединение
3. @RodrigoCaetano вы уже знаете концепцию объединения и кэширования, так что же мешает вам сделать то же самое здесь? Просто сделайте объект connection глобальной / переменной-членом, а не локальной переменной, и поставьте рядом с ним таймер. Если объект не создан, создайте его. В противном случае, если таймер еще не истек, повторно используйте объект. В противном случае уничтожьте и воссоздайте объект. Когда процесс будет завершен, сбросьте таймер.
4. соединение @RemyLebeau уже является переменной класса в одноэлементном (в исходном коде). То, что вы описали, — это оригинальная идея использования timer. У меня просто не очень хороший опыт использования таймеров, поэтому я стараюсь его не использовать. Мой вопрос в том, есть ли другой способ, или таймер действительно является лучшим вариантом здесь
5. @RemyLebeau Итак, согласно вашему ответу, таймер действительно является лучшим подходом.