Форум: "Сети";
Текущий архив: 2006.07.30;
Скачать: [xml.tar.bz2];
ВнизISAPI(dll) разделение общих ресурсов в копиях dll Найти похожие ветки
← →
piople © (2006-03-20 14:35) [0]Доброго времени суток!
Вообщем разрабатываю сайт с использованием ISAPI, все замечательно, но столкнулся с такой проблемой - это общие ресурсы для всех копий dll, то есть, например, запросил пользователь некую страничку, берутся данные обрабатываются и в конечном итоге передаются клиенту... но, потом эти даннные по прежднему остаются в памяти, и при следующей запросе получается дублирование данных...
Детально:
некто запросил: babah.ru -> выполняется скрипт и результат помещается в некую переменную TMPVar -> результат скрипта отправлен пользователю...
следующий пользователь (либо паралельно с первым) выполняет запрос туда же: babah.ru -> выполняется скрипт и результат помещается в некую переменную и тут калапс, получается что в переменной хранятся старые данные и новые!!! -> пользователю уходят ненужные данные...
Казалось бы парень просто обнуляй переменную и все!!! Не хочет все равно... если допустим у меня цикл в моей dll который работает с TStringList и делает в него добавление данных (ADD) и тут же кто-то другой тоже далет запрос туда же (вернее хоть куда где использутеся мой TStringList) то он добавляет данные В ТОТ ЖЕ DLL!
Не знаю что делать... пытался копать в сторону:
const
COINIT_MULTITHREADED = 0;
COINIT_APARTMENTTHREADED = 2;
function CoInitializeEx(pvReserved: pointer; coInit:
Longint): HResult; stdcall;
Параметр pvReserved зарезервирован для будущего использования и должен быть всегда равен nil, а параметр coInit определяет модель потоков создаваемого апартамента. Он может принимать значения COINIT_APARTMENTTHREADED и COINIT_MULTITHREADED. В первом случае для потока создается однопоточный апартамент, причем каждый поток может иметь, а может и не иметь свой апартамент. Во втором случае, если в текущем процессе еще не создан многопоточный апартамент, он создается. Если же многопоточный апартамент уже создан другим потоком, текущий поток подключается к готовому апартаменту. Другими словами, каждый процесс может иметь только один многопоточный апартамент. Вышеописанная функция возвращает значение S_OK в случае успешного создания апартамента. Каждому вызову CoInitializeEx должен соответствовать вызов CoUninitialize. То есть, если вы работаете с СОМ в приложении, функция CoInitializeEx должна быть вызвана до первого вызова функций СОМ, а CoUninitialize должна быть вызвана по завершении работы приложения. По завершении работы с СОМ (или перед завершением работы) поток должен уничтожить апартамент путем вызова процедуры CoUninitialize. Библиотека VCL выполняет автоматическую инициализацию СОМ при использовании модуля ComObj, и по умолчанию создается однопоточный апартамент. Если вам в приложении необходима другая модель потоков, следует внести исправления в файл проекта *.dpr, установив флаг инициализации СОМ до оператора Application.Initialize:
program Project1;
uses
Forms, ComObj, ActiveX,
Unit1 in "Unit1.pas" {Form1};
{$R *.RES}
begin
CoInitFlags := COINIT_MULTITHREADED;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
к сожалению ничего не нашел...
← →
Сергей М. © (2006-03-20 14:58) [1]
> в некую переменную TMPVar
library MyISAPIlib;
...
threadvar
TMPVar: SomeType;
begin
..
IsMultiThread := True;
..
end.
← →
piople © (2006-03-20 15:16) [2]К сожалению результат тот же...
← →
Сергей М. © (2006-03-20 15:56) [3]Приводи код
← →
piople © (2006-03-21 05:38) [4]хе... думаю многовато будет...
Что именно мне надо представить? Это обычный ISAPI...
← →
Сергей М. © (2006-03-21 08:49) [5]Ну где у тебя эта самая TMPVar объявлена ?
← →
piople © (2006-03-21 09:32) [6]TMPVar это мой TStringList объявлен в общем VAR...
← →
Сергей М. © (2006-03-21 09:36) [7]
> piople © (21.03.06 09:32) [6]
> объявлен в общем VAR
Где объявлена-то ?
Статическая это переменная или локальная ?
← →
piople © (2006-03-21 11:14) [8]
> unit main;
>
> interface
>
> uses
> SysUtils, Classes, HTTPApp, DB, ADODB, HTTPProd, DBWeb,
> DBBdeWeb, StrUtils, windows,
> mshtml, activex, OleCtrls, SHDocVw, variants, StdCtrls,
> Math;
>
> type
> TWebModule1 = class(TWebModule)
> Tmpl: TPageProducer;
> Query: TADOQuery;
> DQuery: TADOQuery;
> ADOConnection: TADOConnection;
> ADOCommand: TADOCommand;
>
> { Private declarations }
> public
>
> { Public declarations }
> end;
>
> var
> WebModule1: TWebModule1;
> MainS, news, Top10 : TStringList; ВОТ ТУТ :)
>
> implementation
>
> uses Dialogs, DateUtils;
>
> {$R *.dfm}
← →
Сергей М. © (2006-03-21 11:31) [9]А где конструируешь-разрушаешь эттот объект ?
← →
piople © (2006-03-21 12:31) [10]Создал...
procedure TWebModule1.WebModuleCreate(Sender: TObject);
begin
....
news := TStringList.create; //Новостная лента
MainS := TStringList.Create; //Тело форума
Top10 := TStringList.Create; //10 последних сообщений
...
end;
Убил...procedure TWebModule1.WebModuleDestroy(Sender: TObject);
begin
news.Free;
MainS.Free;
Top10.Free;
end;
← →
Сергей М. © (2006-03-21 12:50) [11]см. событие TWebActionItem.OnAction
в его обработчике :
var TMPVar: TStringList;
begin
TMPVar := TStringList.Create;
try
... обрабатываешь акцию
finally
TMPVar.Free;
end;
end;
← →
piople © (2006-03-22 09:40) [12]К сожалению данные метод не реализуем в моей функции, так как я еще использую TPageProducer и у него свои процедуры/функции использующие те же стринглисты... :(
← →
Сергей М. © (2006-03-22 10:50) [13]
> piople © (22.03.06 09:40) [12]
Все равно мне не понятно, почему вариант с глобальной threadvar-переменной не проходит .. Обязан проходить !
← →
Сергей М. © (2006-03-22 10:59) [14]threadvar
Myvar: TStrings;
В событии BeforeDispatch:
Myvar := TStringsList.Create;
В событии AfterDispatch:
FreeAndNil(Myvar);
← →
WondeRu © (2006-03-22 11:50) [15]The threadvar section can only be used for global variables. Pointer and Function variables can"t be thread variables. Types that use copy-on-write semantics, such as long strings don"t work as thread variables either.
← →
Сергей М. © (2006-03-22 12:12) [16]
> WondeRu © (22.03.06 11:50) [15]
Это несколько из другой оперы.
Убедись, что следующий код успешно работает:
threadvar
SL: TStringList; // SL по сути и есть Pointer
type
TMyThread = class(TThread)
private
FNum: Integer;
FList: TStrings;
procedure ShowList;
protected
procedure Execute; override;
constructor Create(ThreadNum: Integer);
end;
{ TMyThread }
constructor TMyThread.Create(ThreadNum: Integer);
begin
FNum := ThreadNum;
inherited Create(False);
end;
procedure TMyThread.Execute;
var
i: Integer;
begin
FreeOnTerminate := True;
FList := TStringList.Create;
SL:= TStringList.Create;
for i:= FNum to FNum + 50 do
SL.Add(IntToStr(i));
FList.Assign(SL);
Synchronize(ShowList);
SL.Free;
FList.Free;
end;
procedure TMyThread.ShowList;
var
i: Integer;
begin
for i:= 0 to FList.Count - 1 do
Form1.Memo1.Lines.Add("ThreadNum = " + IntToStr(FNum) + " StringList[" + IntToStr(i) + "] = " + FList[i]);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
TMyThread.Create(1);
TMyThread.Create(2);
end;
← →
WondeRu © (2006-03-22 12:13) [17]Сергей М. © (22.03.06 12:12) [16]
SL: TStringList; // SL по сути и есть Pointer
сам же написал... почему, Сергей, это другое?
← →
Сергей М. © (2006-03-22 12:33) [18]
> WondeRu © (22.03.06 12:13) [17]
Потому что память под эту указательную переменную действительно выделяется в TLS текущего потока, а вот память под объект, на который впоследствии будет указывать эта переменная, выделяется уже не в TLS, а в куче.
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2006.07.30;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.012 c