2013-05-27 3 views
3

VCL (일부 인수가 있음)을 업데이트하는 함수가 주 스레드에서 호출되었는지 여부를 확인한 다음 주 스레드 컨텍스트 내에서 항상 실행되는지 확인하는 스레드 래퍼를 사용하고 있습니다.VCL 스레드 래퍼 코드 단순화

작동하지만 간단하게 만들고 싶습니다. 문제는 VCL 동기화가 필요한 모든 함수에서이 코드를 반복해야 오류가 발생하기 쉽다는 것입니다. 이 래퍼를 더 간단하고 재사용 할 수있는 방법이 있습니까? 이 특정 래퍼는 하나의 매개 변수만을 사용하지만, TLocalArgs에 복사되고 전달되는 매개 변수의 개수는 제한 될 수 있습니다.

현재 코드 :

boost::scoped_ptr<TIdThreadComponent> WorkerThread; 

... 

void TForm1::SetMemoMessage(UnicodeString Msg) 
{ 
// Check which thread called function, main thread or worker thread 
if (GetCurrentThreadId() != System::MainThreadID) 
    { 
    struct TLocalArgs 
     { 
     TForm1 *Form; 
     UnicodeString Msg; 
     void __fastcall SetMemoMessage() // Same name as main function to make it easier to maintain 
      { 
      // We are in main thread now, safe to call message update directly 
      Form->SetMemoMessage(Msg); 
      } 
     }; 

    // We are in worker thread, wrap into Synchronize 
    TLocalArgs Args = { this, Msg }; 
    WorkerThread->Synchronize(&Args.SetMemoMessage); 
    return; 
    } 

// MAIN THREAD CODE is very simple compared to wrapper above 
Memo1->Text = Msg; 
} 

답변

5

TThread::Synchronize() 확인 당신을 위해 내부적으로 MainThreadIDSynchronize()가 메인 스레드에서 호출 직접 경우 지정된 프로 시저를 호출합니다. 무조건 Synchronize()으로 전화하여 세부 사항을 처리하도록하십시오. Synchronize()에는 정적 버전이 너무 많이 오버로드되어 있으므로 TThread 포인터를 호출 할 필요가 없습니다.

이 시도 :

void TForm1::SetMemoMessage(UnicodeString Msg) 
{ 
    struct TLocalArgs 
    { 
     UnicodeString Msg; 
     void __fastcall SetMemoMessage() 
     { 
      Form1->Memo1->Text = Msg; 
     } 
    }; 

    TLocalArgs Args; 
    Args.Msg = Msg; 
    TThread::Synchronize(NULL, &Args.SetMemoMessage); 
} 
+0

감사합니다, 내 버전을 통해 확실히 개선. – Coder12345

+0

은 Builder C++ 6에서 작동하지 않습니다. [C++ 오류] main.cpp (100) : E2247 '_fastcall TThread :: Synchronize (void (_fastcall * (_closure)())())'액세스 할 수 없습니다. ' –

+0

@AndreiKrasutski correct C++ Builder 6에서 정적이 아닌 과부하가'protected'되었습니다 (Delphi 7에서 Synchronize()의'static' 오버로드가 추가되었습니다 (BDS 2006까지는 C++ Builder에서는 나타나지 않았습니다). 'TThread' 파생 클래스 안에서만 사용할 수 있습니다. 문제의 코드는'UnicodeString'을 사용합니다. RADStudio 2009 이후 버전입니다. 여기서 정적이 아닌 오버로드는'public'입니다. –