|
Уничтожение критической сексии и деструктор потокв
#40057465
Ссылка:
Ссылка на сообщение:
Ссылка с названием темы:
|
|
|
|
Доброго времени суток товарищи, есть функция RunThread, которая создает потоки для обработки массивов, как вызвать деструктор потоков и критической секции по окончании обработки массива.
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253. 254. 255. 256. 257. 258. 259. 260. 261. 262. 263. 264. 265. 266. 267. 268. 269. 270. 271. 272. 273. 274. 275. 276. 277. 278. 279. 280. 281. 282. 283. 284. 285. 286.
unit UnitImageConvertor;
interface
uses
System.SysUtils,
System.Classes,
System.Threading,
System.SyncObjs,
System.Math,
Vcl.Imaging.jpeg,
Vcl.Graphics,
Vcl.Imaging.pngimage,
Vcl.FileCtrl,
Vcl.Forms;
type
TArrayNameFile = array of string;
TThreadImage = class(TThread)
protected
{$IFDEF TTREAD}
procedure Execute; override;
{$ENDIF}
end;
type
TMyClass = class(TObject);
//private
//FResult: Int64;
{$IFDEF TASK}
procedure RunParalel(const AArraySourceNameFile, AArrayFinishNameFile:TArrayNameFile;
const ALengthArray: Integer);
{$ENDIF}
{$IFDEF TTREAD}
procedure RunThread(const AArraySourceNameFile, AArrayFinishNameFile: TArrayNameFile;
const ALengthArray: Integer);
{$ENDIF}
function LoadImageFromFile(const ASourceNameFile: PChar): THandle;
procedure SaveImageToFile(const AImageHandle: THandle; AFinishNameFile: PChar);
procedure FreeImage(const AImageHandle: THandle);
var
ArrayThread: array [0..16] of TThreadImage;
{ENDIF TASK}
implementation
uses
FiveProgect;
{$IFDEF TTREAD}
var
PositionThread, LengthArray, ExitThread: Integer;
ArrayOldNameFile, ArrayNewNameFile: array of string;
MyObject: TMyClass;
CriticalSectionThread: TCriticalSection;
procedure RunThread(const AArraySourceNameFile, AArrayFinishNameFile: TArrayNameFile;
const ALengthArray: Integer);
var
I, CountTthread: Integer;
begin
LengthArray := ALengthArray;
PositionThread := 0;
Form1.ProgressBarConvert.Max := ALengthArray;
Form1.ProgressBarConvert.Position := 0;
SetLength(ArrayOldNameFile, ALengthArray);
SetLength(ArrayNewNameFile, ALengthArray);
ExitThread := 0;
for I := 0 to LengthArray - 1 do
begin
ArrayOldNameFile[I] := AArraySourceNameFile[I];
ArrayNewNameFile[I] := AArrayFinishNameFile[I];
end;
CriticalSectionThread := TCriticalSection.Create;
CountTthread := 2 * System.CPUCount;
for I := 0 to CountTthread - 1 do
begin
ArrayThread[I] := TThreadImage.Create(True);
ArrayThread[I].Priority := tpNormal;
end;
For I := 0 to CountTthread - 1 do
begin
ArrayThread[I].Start;
end;
while True do
begin
if ExitThread < ALengthArray then
sleep(3000)
else
begin
CriticalSectionThread.Free;
Exit
end;
end;
end;
{$ENDIF}
function LoadImageFromFile(const ASourceNameFile: PChar): THandle;
var
LBmpFile: TBitmap;
LJPEGFile: TJPEGImage;
LPngFile: TPNGObject;
begin
LBmpFile := TBitmap.Create;
if AnsiUpperCase(ExtractFileExt(string(ASourceNameFile))) = '.BMP' then
begin
try
LBmpFile.LoadFromFile(string(ASourceNameFile));
Result := THandle(LBmpFile);
finally
end;
end
else if (AnsiUpperCase(ExtractFileExt(string(ASourceNameFile))) = '.JPG') then
begin
LJPEGFile := TJPEGImage.Create;
try
LJPEGFile.CompressionQuality := 100;
LJPEGFile.LoadFromFile(string(ASourceNameFile));
LBmpFile.Assign(LJPEGFile);
Result := THandle(LBmpFile);
finally
LJPEGFile.Free;
end;
end
else if (AnsiUpperCase(ExtractFileExt(ASourceNameFile)) = '.PNG') then
begin
LPngFile := TPNGObject.Create;
try
LPngFile.LoadFromFile(ASourceNameFile);
LBmpFile.Assign(LPngFile);
Result := THandle(LBmpFile);
finally
LPngFile.Free;
end;
end;
end;
procedure SaveImageToFile(const AImageHandle: THandle; AFinishNameFile: PChar);
var
LBmpFileSource: TBitmap;
LJPEGFile: TJPEGImage;
LPngFile: TPNGObject;
begin
LBmpFileSource := TBitmap(AImageHandle);
if AnsiUpperCase(ExtractFileExt(AFinishNameFile)) = '.BMP' then
begin
LBmpFileSource.SaveToFile(AFinishNameFile)
end
else if AnsiUpperCase(ExtractFileExt(AFinishNameFile)) = '.JPG' then
begin
LJPEGFile := TJPEGImage.Create;
try
LJPEGFile.Assign(LBmpFileSource);
LJPEGFile.SaveToFile(AFinishNameFile);
finally
LJPEGFile.Free;
end;
end
else if AnsiUpperCase(ExtractFileExt(AFinishNameFile)) = '.PNG' then
begin
LPngFile := TPNGObject.Create;
try
LPngFile.Assign(LBmpFileSource);
LPngFile.SaveToFile(AFinishNameFile);
finally
LPngFile.Free;
end;
end;
end;
procedure FreeImage(const AImageHandle: THandle);
begin
TObject(AImageHandle).Free;
end;
{$IFDEF TASK}
procedure RunParalel(const AArraySourceNameFile, AArrayFinishNameFile: TArrayNameFile;
const ALengthArray: Integer);
var
LHandleImage: THandle;
Task: ITask;
I1: integer;
begin
I1 := 0;
Form1.ProgressBarConvert.Max := ALengthArray;
Form1.ProgressBarConvert.Position := 0;
TParallel.For(0, ALengthArray-1, procedure(I : integer)
var
FileName: string;
begin
//
FileName := AArraySourceNameFile[i];
LHandleImage:= LoadImageFromFile(Pchar(FileName));
if LHandleImage > 0 then
begin
SaveImageToFile(LHandleImage, PChar(AArrayFinishNameFile[i]));
//Position := I;
TThread.Queue(nil,
procedure
begin
Form1.ProgressBarConvert.Position := Form1.ProgressBarConvert.Position + 1;
Application.ProcessMessages;
end);
//PositionProgressBar
end;
end
);
end;
{$ENDIF}
{$IFDEF TTREAD}
{ TMyThread }
procedure TThreadImage.Execute;
var
LImageHandle: THandle;
I: Integer;
begin
inherited;
while PositionThread < LengthArray do
begin
CriticalSectionThread.Enter;
PositionThread := PositionThread + 1;
I := PositionThread - 1;
CriticalSectionThread.Leave;
LImageHandle := LoadImageFromFile(PChar(ArrayOldNameFile[I]));
SaveImageToFile(LImageHandle, PChar(ArrayNewNameFile[I]));
FreeImage(LImageHandle);
Synchronize(procedure
begin
Form1.ProgressBarConvert.Position := Form1.ProgressBarConvert.Position + 1;
end);
CriticalSectionThread.Enter;
ExitThread := ExitThread + 1;
CriticalSectionThread.Leave;
end;
Exit;
end;
{$ENDIF}
end.
|
|
|