안녕하세요?
조금은 막연한 문제지만 해결하는 방법도 막연해서 이렇게 질문란에 올립니당..혹시 소스에 문제가 있는지 고수님들이 봐주세영~ 고수님의 지도 부탁드릴께용~ ^-^;;
다음 루틴은 파라미터로 넘어온 string형 data를 zlib압축으로 풀어서 파라미터러 넘어온 TCanvas형 canvs에다가 bitmap을 그려주는건데요.
문제는 이 루틴을 굉장히 빨리 반복(쓰래드 처리)하면 어느정도(어떨때는 1분정도, 또 어떨때는 5초정도로 고정되있지 않음) 있으면 파라미터러 넘어온 canvs가 갑자기 하얗게 되어서 그후로는 bitmap이 그려지지 않아여..데이터는 정상적으로 넘어오는데도 말이죠..ㅡ.ㅡ;; 어디서 문제가 생기는지 통 모르겠습니다.
procedure UnCompressBitmap(const Data: string; canvs: TCanvas; x, y: integer; ms: TMemoryStream; bmp: TBitmap);
var
buf: pointer;
size: integer;
begin
if Length(Data) <= 0 then Exit;
try
DecompressBuf(@Data[1], Length(Data), Length(Data) * 3, buf, size);
except
on E: Exception do
begin
E.Message := Format('윽..압축풀다 에러났다. Error Decompressing Buffer (Len = %d):'#13#10'%s',
[Length(Data), e.Message]);
raise;
end;
end;
ms.Position := 0;
ms.Write(buf^, size);
FreeMem(buf);
ms.Position := 0;
// Assert(bmp<>nil);
bmp.LoadFromStream(ms);
canvs.Draw(x, y, bmp);
end;
자답으로 올릴께여~ 쓰래드의 Synchronize 함수로 해결했습니당~ ^^;;
쓰래드에서 안전하게 VCL을 다루기 위해서 Synchronize함수를 쓰다고 도움말에 나오네여
영어가 짧아서 명쾌한 번역은 안되네여.. ^^;; 정확한 내용은 직접 확인해 주세여~ ^^
이하원문=========================================================================
When you use objects from the VCL object hierarchy, their properties and methods are not guaranteed to be thread-safe. That is, accessing properties or executing methods may perform some actions that use memory which is not protected from the actions of other threads. Because of this, a main VCL thread is set aside for access of VCL objects. This is the thread that handles all Windows messages received by components in your application.
If all objects access their properties and execute their methods within this single thread, you need not worry about your objects interfering with each other. To use the main VCL thread, create a separate routine that performs the required actions. Call this separate routine from within your thread뭩 Synchronize method. For example:
procedure TMyThread.PushTheButton;
begin
Button1.Click;
end;
procedure TMyThread.Execute;
begin
...
Synchronize(PushTheButton);
...
end;
Synchronize waits for the main VCL thread to enter the message loop and then executes the passed method.
Note: Because Synchronize uses the message loop, it does not work in console applications. You must use other mechanisms, such as critical sections, to protect access to VCL objects in console applications.
You do not always need to use the main VCL thread. Some objects are thread-aware. Omitting the use of the Synchronize method when you know an object뭩 methods are thread-safe will improve performance because you don뭪 need to wait for the VCL thread to enter its message loop. You do not need to use the Synchronize method in the following situations:
Data access components are thread-safe as long as each thread has its own database session component. The one exception to this is when you are using Access drivers. Access drivers are built using the Microsoft ADO library, which is not thread-safe.
When using data access components, you must still wrap all calls that involve data-aware controls in the Synchronize method. Thus, for example, you need to synchronize calls that link a data control to a dataset by setting the DataSet property of the data source object, but you don뭪 need to synchronize to access the data in a field of the dataset.
For more information about using database sessions with threads, see Managing multiple sessions.
Graphics objects are thread-safe. You do not need to use the main VCL thread to access TFont, TPen, TBrush
, TBitmap, TMetafile, or TIcon. Canvas objects can be used outside the Synchronize method by locking them.
While list objects are not thread-safe, you can use a thread-safe version, TThreadList, instead of TList.