<form action="product.php" method="post" name="frmProduct" id="frmProduct" enctype="multipart/form-data">
<input id="submit_value" type="button" name="submit_value" value="">
</form>
<script type="text/javascript">
document.getElementById("submit_value").onclick = submitAction;
function submitAction()
{
document.getElementById("frmProduct").submit();
return false;
}
</script>
EDIT: я случайно поменял идентификатор вокруг
(Не), к счастью, вы не можете заблокировать произвольные объекты в Delphi 6 (хотя вы можете это сделать в более поздних версиях, 2009 и более поздних), поэтому вам нужен отдельный объект блокировки, обычно критический раздел.
TCriticalSection (примечание: документация из FreePascal, но она существует и в Delphi):
Пример кода:
type
TSomeClass = class
private
FLock : TCriticalSection;
public
constructor Create();
destructor Destroy; override;
procedure SomeMethod;
end;
constructor TSomeClass.Create;
begin
FLock := TCriticalSection.Create;
end;
destructor TSomeClass.Destroy;
begin
FreeAndNil(FLock);
end;
procedure TSomeClass.SomeMethod;
begin
FLock.Acquire;
try
//...do something with mySharedObj
finally
FLock.Release;
end;
end;
Хотя это не так просто, как C #, следующее может сработать для вас.
with Lock(mySharedObj) do
begin
//...do something with mySharedObj
UnLock;
end;
Вкратце
(mySharedObj)
, во внутреннем списке выполняется поиск существующей блокировки. Если существующая блокировка не найдена, будет создана новая блокировка. Новый поток будет заблокирован, если другой поток все еще имеет блокировку. Разблокировка
необходима, потому что мы не можем быть уверены, что ссылка только на экземпляр ILock выйдет из области в конце метода, вызывающего Lock
. (Если бы мы могли, разблокировку
можно было бы удалить). Обратите внимание, что в этом проекте один TLock создается для каждого экземпляра объекта, который вы хотите защитить, без его освобождения до завершения работы приложения.
Это можно было бы учесть, но это потребовало бы возиться с _AddRef & _Release.
unit uLock;
interface
type
ILock = interface
['{55C05EA7-D22E-49CF-A337-9F989006D630}']
procedure UnLock;
end;
function Lock(const ASharedObj: TObject): ILock;
implementation
uses
syncobjs, classes;
type
_ILock = interface
['{BAC7CDD2-0660-4375-B673-ECFA2BA0B888}']
function SharedObj: TObject;
procedure Lock;
end;
TLock = class(TInterfacedObject, ILock, _ILock)
private
FCriticalSection: TCriticalSection;
FSharedObj: TObject;
function SharedObj: TObject;
public
constructor Create(const ASharedObj: TObject);
destructor Destroy; override;
procedure Lock;
procedure UnLock;
end;
var
Locks: IInterfaceList;
InternalLock: TCriticalSection;
function Lock(const ASharedObj: TObject): ILock;
var
I: Integer;
begin
InternalLock.Acquire;
try
//***** Does a lock exists for given Shared object
for I := 0 to Pred(Locks.Count) do
if (Locks[I] as _ILock).SharedObj = ASharedObj then
begin
Result := ILock(Locks[I]);
Break;
end;
//***** Create and add a new lock for the shared object
if not Assigned(Result) then
begin
Result := TLock.Create(ASharedObj);
Locks.Add(Result);
end;
finally
InternalLock.Release;
end;
(Result as _ILock).Lock;
end;
{ TLock }
constructor TLock.Create(const ASharedObj: TObject);
begin
inherited Create;
FSharedObj := ASharedObj;
FCriticalSection := TCriticalSection.Create;
end;
destructor TLock.Destroy;
begin
FCriticalSection.Free;
inherited Destroy;
end;
procedure TLock.Lock;
begin
FCriticalSection.Acquire;
end;
function TLock.SharedObj: TObject;
begin
Result := FSharedObj;
end;
procedure TLock.UnLock;
begin
FCriticalSection.Release;
end;
initialization
Locks := TInterfaceList.Create;
InternalLock := TCriticalSection.Create;
finalization
InternalLock.Free;
Locks := nil
end.
Как сказано, для короткого кода, который не вызывает вне локальной области и не требует каких-либо других блокировок, вы можете использовать критические секции через SyncObjs.TCriticalSection
,
для более длинного / более сложного кода вы можете использовать SyncObjs.TMutex
, который является ожидаемым (с тайм-аутом), не останавливается, если поток-владелец умирает, и может использоваться по имени с другими процессами.
Использование этих оболочек упрощает внесение изменений в уровень синхронизации.
Во всех случаях остерегайтесь драконов: мой ответ на Разница между функцией WaitFor для TMutex delphi и ее эквивалентом в Win32 API
В Delphi 6 нет эквивалента. Начиная с Delphi 2009, вы можете использовать методы System.TMonitor
для захвата блокировок произвольных объектов.
System.TMonitor.Enter(obj);
try
// ...
finally
System.TMonitor.Exit(obj);
end;
(Префикс "System" нужен потому, что имя TMonitor конфликтует с типом в блоке Forms. Альтернативой является использование глобальных функций MonitorEnter
и MonitorExit
)