我需要能够将项目添加到线程内的列表框中。代码如下:
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. };
我收到错误
第Error: a nonstatic member reference must be relative to a specific object
行14.
有没有办法让我这样做?因为如果我尝试在该线程之外使用String^ meep;
,它不包含任何内容。当我在线程中使用它但不在它之外时它完美地工作。我需要能够将该消息添加到列表框中。如果有人可以提供帮助,我会很感激。
答案 0 :(得分:0)
您没有显示如何定义lbxMessages,但我将假设它是同一类中的非静态数据成员。如果是这种情况,那么您需要指定要访问lbxMessages
的对象。最简单的方法是将RecieveThread方法切换为非静态方法,然后您可以访问this->lbxMessages
。
您没有说明您正在使用哪个窗口工具包,但您可能需要重新调用UI线程才能编辑控件。
答案 1 :(得分:0)
一种方法是使用带有ParameterizedThreadStart委托的System :: Thread,它允许您传递对象,在本例中为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);
}
}