|
님과 같이 TServerSocket을 써보지는 않아지만..
[방법1]
일반적인 경우에 자료를 관리하게 위해서 포인터를 저장합니다.
TListView의 TListItem에 보면 Data라는 void * 가 있고
TTreeView의 TTreeNode에도 Data라는 void* 가 있고
..TStringGrid에도 있구요..
TServerClientThread 에도 Data라는 void*가 있습니다.
만약 TServerSocket 에서 수신된 thread를 ListView같은데 보여준다면?
1. ListView에 아이템을 하나 추가하고요(Items->Add())
2. 추가된 Item의 Data 에 thread를 저장합니다.
3. 그리고 thread의 Data에는 Item을 저장하고요...
그렇게 해놓으면 item을 알면 바로 thread에 접근할수 있고
thread를 알면 바로 listview의 item에 접근할수 있겠죠
ServerSocket1ThreadEnd 에서 ListView의 아이템을 삭제하려면?
thread의 Data가 곧 ListView의 Item이므로 바로 삭제가 가능하죠
[샘플]
TreeView 나 ListView 같은경우 ...
void __fastcall TForm1::ServerSocket1GetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket, TServerClientThread *&SocketThread)
{
TListItem *item=ListView1->Items->Add();
item->Caption=IntToStr(SocketThread->ThreadID);
item->Data=SocketThread;
SocketThread->Data =item;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ThreadEnd(TObject *Sender,
TServerClientThread *Thread)
{
TListItem *item=(TListItem *)Thread->Data;
item->Delete();
}
//---------------------------------------------------------------------------
근데 문제는 ComboBox에 저장한다는 것입니다.
ComboBox는 ListView처럼 각 Item이 Object는 아니기 때문에.. thread에 아이템을 저장할수가 없겠죠..
item에는 AddObject로 저장이 가능하지만...
해결방법은 똑같습니다.
win32에서 포인터 4Byte입니다.
이 4Byte를 어떤 객체에 포인터로 보면 포인터인것이고 , 정수로 보면 정수 , 실수로 보면 실수가 되는것이죠
그래서 ComboBox에 item을 add하면 add한 index를 알수 있는데...
그 Index를 void*에 저장합니다. 근데 이경우는 중간에 하나 빠지게 되면.. index가 꼬이게 되겠죠...
[샘플]
ComboBox 나 ListBox 같은경우..
//=============================================================================
void __fastcall TForm1::ServerSocket1GetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket,
TServerClientThread *&SocketThread)
{
int idx=ComboBox1->Items->AddObject(IntToStr(SocketThread->ThreadID), SocketThread);
SocketThread->Data = (void *)idx;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ThreadEnd(TObject *Sender,
TServerClientThread *Thread)
{
int idx=(int)Thread->Data;
ComboBox1->Items->Delete(idx);
TServerClientThread *ThreadTemp;
for(int i=idx;i<ComboBox1->Items->Count;i++) //특정index에 item을 삭제하면 index가 꼬이게 된다...
{
ThreadTemp=(TServerClientThread *)ComboBox1->Items->Objects[i];
ThreadTemp->Data=(void *)i;
}
}
//---------------------------------------------------------------------------
[방법2]
님은 ServerSocket1ThreadEnd 이벤트에서
Thread->ThreadID 로 index를 찾아서 item을 delete하는데요..
만약 Thread->ThreadID 가 꼬인다면? for문 돌려서 직접 Object 끼리 비교해서 처리하는게
좀더 확실한것 같구요
이런식으로...
for(int i=0;i<ComboBox1->Items->Count;i++)
{
ThreadTemp=(TServerClientThread *)ComboBox1->Items->Objects[i];
if(ThreadTemp==Thread)
{
ComboBox1->Items->Delete(i);
return;
}
}
또한 님은 Thread->ThreadID 를 string key로 만들어서
ComboBox->Items->IndexOf()라는 함수를 이용하여 index를 찾는데요
ComboBox1->Items->IndexOfObject(Thread)를 이용하면 더욱 확실하지 않을까 싶습니다.
-추신-
밑에 코드에서 보면
AuthServerSocketGetThread 에서는
TServerClientThread *&SocketThread 를 받아서 addObject 하셨는데...
AuthServerSocketThreadEnd 함수에서 for문 돌릴때
TServerSocketThread 로 type cast하신거죠?
//((TServerSocketThread*)ThreadObjectCombo->Items->Objects[nIndex]
잘모르는데.. ThreadStart , ThreadEnd 이벤트에 서로 짝을 맞추는것이 좋지 않나요?
(정말 잘 모르는 부분입니다.)
그럼...
짱구오빠 님이 쓰신 글 :
: TServerSocketThread 생성과 종료 이벤트 소스입니다.
:
: 동시에 여러개의 쓰래드를 처리할 경우
: 생성이벤트에서 생성된 쓰래드 아이디를 콤보 박스에 저장한 후
: 종료할때 종료된 쓰래드 아이디를 콤보 박스에서 검색해서 해당 쓰래드 아이디를 삭제하는데요.
:
: 처리하다보면 가끔
: 생성된 쓰래드 아이디와 종료된 쓰래드 아이디가 틀리게 응답될 경우가 있습니다.
: 즉, 생성할때 쓰래드 아이디가 10이였는데
: 10번 쓰래드가 종료될때 쓰래드 아이디값이 120 이런식으로 됩니다.
:
: 이런 경우는 어떻게 처리해야하나요.
:
: 부탁드립니다. ^^;;;;
:
: --------------------------------------------------------------------------------------
:
:
:
: //---------------------------------------------------------------------------
: //Socket Thread Create Event
: //---------------------------------------------------------------------------
: void __fastcall Tfkmsmain::AuthServerSocketGetThread(TObject *Sender,
: TServerClientWinSocket *ClientSocket,
: TServerClientThread *&SocketThread)
: {
: //TServerClientThread 를 생성
: SocketThread = new TServerSocketThread(false, ClientSocket);
:
: //Thread Object, Socket handle Insert
: ThreadObjectCombo->Items->AddObject(IntToStr(SocketThread->ThreadID), SocketThread);
: }
:
:
: //---------------------------------------------------------------------------
: //Socket Thread End Event
: //---------------------------------------------------------------------------
: void __fastcall Tfkmsmain::AuthServerSocketThreadEnd(TObject *Sender,
: TServerClientThread *Thread)
: {
: //Close Socket Handle Search
: //ListBox2->Items->Add(IntToStr(Thread->ThreadID));
: int nObjectIndex = ThreadObjectCombo->Items->IndexOf(IntToStr(Thread->ThreadID));
: if (nObjectIndex >= 0) ThreadObjectCombo->Items->Delete(nObjectIndex);
: else if (nTerminateStandbyCount > 0) nTerminateStandbyCount--;
: //Invalid Thread ID Terminate Found
: else
: {
: try
: {
: //Execution Thread Terminate
: DWORD dwResult;
: for (int nIndex = 0; nIndex < ThreadObjectCombo->Items->Count; nIndex++)
: {
: Application->ProcessMessages();
: if ((TServerSocketThread*)ThreadObjectCombo->Items->Objects[nIndex] == NULL ||
: (GetExitCodeThread((void*)(((TServerSocketThread*)ThreadObjectCombo->Items->Objects[nIndex])->Handle), &dwResult) == false &&
: dwResult != STILL_ACTIVE))
: {
: //Object Delete
: ThreadObjectCombo->Items->Delete(nIndex);
: continue;
: }
: }
: }
: __except(EXCEPTION_EXECUTE_HANDLER)
: {
: }
: }
: }
|