2012-12-20 1 views
0

스레드 내부의 목록 상자에 항목을 추가 할 수 있어야합니다. system :: thread에서 컨트롤을 편집하는 방법.

1. ref class Work 
2. { 
3. public: 
4. static void RecieveThread() 
5.  { 
6.  while (true) 
7.  { 
8.   ZeroMemory(cID, 64); 
9.   ZeroMemory(message, 256); 
10.   if(recv(sConnect, message, 256, NULL) != SOCKET_ERROR && recv(sConnect, cID, 64, NULL) != SOCKET_ERROR) 
11.   { 
12.    ID = atoi(cID); 
13.    String^ meep = gcnew String(message); 
14.    lbxMessages->Items->Add(meep); 
15.    check = 1; 
16.   } 
17.  } 
18. } 
19. }; 

내가 라인 14.

Error: a nonstatic member reference must be relative to a specific object이 나를 그렇게하게 갈 수있는 방법이 있나요 오류를 얻을 : 아래 코드는 무엇입니까? 그 스레드 외부에 String^ meep;을 사용하려고하면 아무 것도 포함하지 않기 때문에. 쓰레드 내에서 사용할 때 PERFECT가 작동하지만 외부에서는 사용되지 않습니다. 해당 메시지를 목록 상자에 추가 할 수 있어야합니다. 누구든지 도와 주시면 감사하겠습니다.

답변

0

lbxMessages가 정의 된 방법을 표시하지 않지만 동일한 클래스의 비 정적 데이터 멤버라고 가정합니다. 이 경우 lbxMessages에 액세스 할 개체를 지정해야합니다. 가장 간단한 방법은 RecieveThread 메서드를 비 정적으로 전환 한 다음 this->lbxMessages에 액세스 할 수 있습니다.

사용중인 윈도우 툴킷을 말하지 않았지만 컨트롤을 편집하려면 UI 스레드로 다시 호출해야합니다.

0

한 가지 방법은 System :: Thread를 ParameterizedThreadStart 대리자와 함께 사용하여 개체 (이 경우 lbxMessages)를 전달할 수있게하는 것입니다. 스레드를 실행하기위한

ParameterizedThreadStart^ threadCallback; 
threadCallback = gcnew ParameterizedThreadStart(&Work::ReceiveThread); 
Thread^ recvThread = gcnew Thread(threadCallback); 
recvThread->Start(lbxMessages); 

정적 방법 :

static void RecieveThread(Object^ state) 
{ 
    ListBox^ lbxMessages = (ListBox^)state; 
    //...code 
} 

하지만 .... 또 다른 문제가있다. ListBox가 Win32 컨트롤이라고 가정하면 컨트롤이 작성된 스레드에서만 컨트롤을 변경할 수 있습니다. 따라서 ListBox 항목을 삽입 할 때마다 UI 스레드에서 완료해야합니다. 한 가지 방법은 SynchronizationContext 개체를 사용하는 것입니다.

// Start the thread 
array<Object^>^ args = gcnew array<Object^>(2){ 
    lbxMessages, 
    SynchronizationContext::Current 
} 
recvThread->Start(args); 

스레드 방법은 다음과 같이해야한다 :

static void RecieveThread(Object^ state) 
{ 
    array<Object^>^ args = (array<Object^>^)state; 
    ListBox^ lbxMessages = (ListBox^)args[0]; 
    SynchronizationContext^ ctx = (SynchronizationContext^)args[1]; 
    //...code 
    String^ meep = gcnew String(message); 
    ctx->Send(gcnew SendOrPostCallback(&Work::SafeListBoxInsert), 
       gcnew array<Object^>(2){lbxMessages, meep} 
    ); 
} 

당신은 다른 방법을 필요가 UI의 스레드에서 호출하고 변경합니다.

ref class Work{ 
    //...other methods 
    static void SafeListBoxInsert(Object^ state) 
    { 
    array<Object^>^ args = (array<Object^>^)state; 
    ListBox^ lst = (ListBox^) args[0]; 
    String^ item = (String^) args[1]; 
    lst->Items->Add(item); 
    } 
} 
관련 문제