2012-03-15 6 views
3

У меня есть некоторые процедуры оптимизации базы данных, которые необходимо выполнять периодически. В настоящее время я использую TTimer, но основной VCL замораживается и очень взломан ... Я хотел бы знать, какой лучший метод - иметь низкое потребление процессора и выполнять эти подпрограммы. Я думаю, что наилучшим способом является выполнение подпрограмм в отдельных потоках с низким приоритетом потока.бесконечные петли в отдельных потоках

Любые идеи?

+0

Просто чтобы убедиться, что эти процедуры выполняются из приложения GUI? –

+0

Да, они ... – opc0de

+0

Являются ли эти процедуры оптимизации фактически частью приложения?Возможно, вы можете их извлекать и периодически выполнять на сервере в задании базы данных, службе или отдельном приложении. Если вы не можете их извлечь, то да, ваш единственный (достойный) вариант, чтобы не замораживать пользовательский интерфейс, состоит в том, чтобы выполнять их в отдельном потоке. –

ответ

0

IMHO, поток с низким приоритетом - это путь для выполнения такого рода задач. Но вам не нужно создавать разные потоки для каждой подпрограммы оптимизации, обрабатывать все из них только одним потоком. Таким образом, вам будет проще выполнить их в определенном порядке или с разными частотами, и вы будете уверены, что они не вступают друг в друга (с точки БД).

+0

Да, но если одна нить зависает (из-за подключения к Интернету), другая может продолжить – opc0de

+0

@ opc0de, что могут сделать другие потоки в такой ситуации? –

+0

Будьте предельно осторожны при использовании приоритетов потоков. Существует множество проблем (таких как [инверсия приоритета] (http://en.wikipedia.org/wiki/Priority_inversion)), которые могут возникнуть в результате их использования. Возможно, лучше всего просто закодировать сами потоки, чтобы добиться прогресса в решении наиболее важных задач. –

1

Один из способов сделать это является созданием вашего «дб оптимизации потоков» что-то вроде:

type 
    // a record defining database connection 
    TConnectionSettings = record 
    DatabaseName: string; 
    Server: string; 
    Port: Word; 
    UserName: string; 
    Password: string; 
    end; 

type 
    TDBOptimizationThread = class(TThread) 
    private 
    FConnection: TDatabaseConnection; // your database connection... I don't know what libraries you are using 
    FQuery: TQuery; // your specific db query 
    protected 
    procedure Execute; override; 
    public 
    constructor Create(AConnectionSettings: TConnectionSettings; 
    destructor Destroy; override; 
    end; 

implementation 

constructor TDBOptimizationThread.Create(AConnectionSettings: TConnectionSettings; 
begin 
    inherited Create(True); // create suspended 
    //FreeOnTerminate := True; // if you want it to be freed when you terminate it 
    // create FConnection and FQuery objects 
    // setup FConnection parameters based on AConnectionSettings 
end; 

destructor TDBOptimizationThread.Destroy; 
begin 
    // destroy objects 
    inherited Destroy; 
end; 

procedure TDBOptimizationThread.Execute; 
begin 
    while NOT Terminated do 
    try 
     // check if it's time to run query 
     // you can use a private variable of TDateTime type that will hold 
     // last timestamp of when the query ran, etc. 
     if ItsTimeToRunQuery then begin 
     // check if we still have db connectivity 
     if NOT FConnection.Connected then 
      // ouch, try to connect... 
      FConnection.Connect; 
     FQuery.SQL.Text := 'Your optimization query'; 
     FQuery.Execute; // or ExecSQL or whatever the method is based on your db library 
     end; 
    except 
     on E: Exception do begin 
     // log exception, something went wrong!! 
     end; 
    end; 
end; 

Это очень важно, что подключение к БД создается и уничтожается в этом потоке, в противном случае вы будете иметь проблем .. .

Итак, давайте начнем с оптимизацией БД нити

... 
var 
    LConnSettings: TConnectionSettings; 
    // you may want a private TDBOptimizationThread variable rather than 
    // a variable in a method, but I leave that to you 
    LDBOptimizationThread: TDBOptimizationThread; 
begin 
    LConnSettings.Database := 'MyDatabase'; 
    LConnSettings.Port := 1234; 
    LConnSettings.Server := 'localhost'; 
    // continue with connection settings... 
    LDBOptimizationThread := TDBOptimizationThread.Create(LConnSettings); 
    LDBOptimizationThread.Start; // start it 
end; 

конечно, Вы можете сделать это с низким приоритетом, но если ваши запросы не будут работать на м руды, чем несколько секунд в каждый раз, я не вижу причины для этого, но не стесняйтесь противоречить.

3

Если возможно, гораздо лучше всего ко всем своим темам сделать все самое главное, что нужно сделать в это конкретное время. Мессинг с приоритетами потоков может привести к тому, что вы не знаете, что именно вы делаете, serious performance problems. Вместо этого просто пропишите свои темы следующим образом:

  1. Есть ли что-нибудь важное? Если да, сделайте это.

  2. Есть ли что-то не слишком важное? Если да, сделайте немного.

  3. Перейти к шагу 1.

Say вы используете приоритеты потоков. Представьте себе следующее:

  1. Задача с низким приоритетом, A, захватывает блокировку базы данных.

  2. Задача с обычным приоритетом, B, требует большого количества процессорного времени, она крадет процессор из задачи с низким приоритетом.

  3. Задача с обычным приоритетом, C, требует доступа к базе данных. Но он не может работать, потому что задача с низким приоритетом содержит блокировку в базе данных, а задача B получает процессор за задачу A.

  4. Теперь задача C должна ждать завершения задачи B, чтобы получить доступ к базе данных , Но это должно быть временное с заданием B.

+0

Возможно, это не очень хороший пример, потому что IMHO задача с низким приоритетом не должна блокировать базу данных в первую очередь. Но ваш главный смысл кажется ясным. –

+0

@AndriyM: Это может быть непреднамеренное последствие одной строки кода, оно может быть даже косвенным с блокировкой в ​​библиотеке. Я выбрал базу данных, потому что он конкретно сказал, что задачей с низким приоритетом является «оптимизация базы данных». –

Смежные вопросы