0

我需要能够将项目添加到线程内的列表框中。代码如下:

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; 在该线程之外使用它不包含任何内容。当我在线程内但不在线程外使用它时,它可以完美运行。我需要能够将该消息添加到列表框中。如果有人可以提供帮助,我将不胜感激。

4

2 回答 2

0

您没有展示如何定义 lbxMessages,但我将假设它是同一类中的非静态数据成员。如果是这种情况,那么您需要指定要访问lbxMessages的对象。最简单的方法是将 RecieveThread 方法切换为非静态方法,然后您可以访问this->lbxMessages.

您没有说您正在使用哪个窗口工具包,但您可能需要 Invoke 回到 UI 线程才能编辑控件。

于 2012-12-20T08:58:03.397 回答
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);
  }
}
于 2012-12-20T09:01:06.607 回答