Spelt / ZXing.Delphi

ZXing Barcode Scanning object Pascal Library for Delphi VCL and Delphi Firemonkey
Apache License 2.0
471 stars 206 forks source link

TScanManager fall in multithread execution #157

Closed Hadgehogs closed 9 months ago

Hadgehogs commented 10 months ago

Hello. Simple example:

`function test(Param: Pointer): THandle; var ScanManager: TScanManager; ReadResult: TReadResult; aBitmap: TBitmap; res: TReadResult; begin aBitmap := TBitmap.Create(); aBitmap.LoadFromFile('C:\data.bmp'); while True do begin ScanManager := TScanManager.Create(TBarcodeFormat.EAN_13, nil); res := ScanManager.Scan(aBitmap); if res <> nil then res.free; ScanManager.free; end; end;

procedure TForm2.Button1Click(Sender: TObject); var pid: Cardinal; begin createthread(nil, 0, @test, 0, 0, pid); createthread(nil, 0, @test, 0, 0, pid); end; ` Get unhandled exception like this: First chance exception at $00000000012D4870. Exception class $C0000094 with message 'c0000094 INTEGER_DIVIDE_BY_ZERO'. Process Project1.exe (11596) at this code point:

изображение

The reason for this is the use of class variables, which can change across threads without locking.

изображение

изображение

Hadgehogs commented 9 months ago

ScanManager := TScanManager.Create(TBarcodeFormat.EAN_13, nil); need change too: ScanManager := TScanManager.Create(TBarcodeFormat.Auto, nil);

Spelt commented 9 months ago

This is not supported. Only one instance is supported.

Your improvement suggestion is probably not the only change to make, I do however accept pull requests :-)

It would be cool to run it parallel on multiple cores.

On 5 Nov 2023, at 21:37, Hadgehogs @.***> wrote:

Hello. Simple example:

`function test(Param: Pointer): THandle; var ScanManager: TScanManager; ReadResult: TReadResult; aBitmap: TBitmap; res: TReadResult; begin aBitmap := TBitmap.Create(); aBitmap.LoadFromFile('C:\data.bmp'); while True do begin ScanManager := TScanManager.Create(TBarcodeFormat.EAN_13, nil); res := ScanManager.Scan(aBitmap); if res <> nil then res.free; ScanManager.free; end; end;

procedure TForm2.Button1Click(Sender: TObject); var pid: Cardinal; begin createthread(nil, 0, @test https://github.com/test, 0, 0, pid); createthread(nil, 0, @test https://github.com/test, 0, 0, pid); end; ` Get unhandled exception like this: First chance exception at $00000000012D4870. Exception class $C0000094 with message 'c0000094 INTEGER_DIVIDE_BY_ZERO'. Process Project1.exe (11596) at this code point:

https://user-images.githubusercontent.com/40996325/280553229-5fc36e57-8b32-413c-b6ad-7a556ce254de.png The reason for this is the use of class variables, which can change across threads without locking.

https://user-images.githubusercontent.com/40996325/280553258-ac6b47f4-b6a2-4656-a48a-8875237ea846.png https://user-images.githubusercontent.com/40996325/280553288-c721e69e-0844-4289-b842-061320daa92b.png — Reply to this email directly, view it on GitHub https://github.com/Spelt/ZXing.Delphi/issues/157, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADAS3VLAYXQP4V2UASP3Y5DYC72HNAVCNFSM6AAAAAA66SPN5SVHI2DSMVQWIX3LMV43ASLTON2WKOZRHE3TOOJVGIZTQNI. You are receiving this because you are subscribed to this thread.