我已经阅读了很多有关这些内容的信息,我试过这个:
class Server
{
...
public Server(int Port, ListBox ex_lb, PictureBox ex_pb)
{
ServerWork = new Thread(() => ServerFunction(Listener, ex_lb, ex_pb));
ServerWork.Start();
}
static void ServerFunction(TcpListener ex_listener, ListBox ex_lb, PictureBox ex_pb)
{
//and any access to ex_lb throws exception, didnt debug to access to ex_pb
}
}
这样:
private static IncomingDataClass g_IDC = new IncomingDataClass();
private class IncomingDataClass
{
static string data = "";
public string Data
{
get { return data; }
set {
data = value;
SomeEvent(this,null,data);
}
}
}
void IncomingDataClass_SomeEvent(object sender, EventArgs e, string ex_data)
{
if (ex_data.Contains("listbox"))
{
ex_data = ex_data.Remove(ex_data.IndexOf("listbox"), "listbox".Length);
listBox1.Items.Add(ex_data);
}
}
delegate void MyEventHandler(object sender, EventArgs e, string ex_data);
static event MyEventHandler SomeEvent;
// in form load event
SomeEvent += IncomingDataClass_SomeEvent;
class Server
{
...
public Server(int Port, ListBox ex_lb, PictureBox ex_pb)
{
ServerWork = new Thread(() => ServerFunction(Listener));
ServerWork.Start();
}
static void ServerFunction(TcpListener ex_listener)
{
//and any change of g_IDC.Data throws exception here
}
}
这样:
private static ListBox listBox1 = new ListBox();
private void Form1_Load(object sender, EventArgs e)
{
...
listBox1.FormattingEnabled = true;
listBox1.Location = new System.Drawing.Point(12, 256);
listBox1.Name = "listBox1";
listBox1.Size = new System.Drawing.Size(258, 108);
listBox1.TabIndex = 6;
Controls.Add(listBox1);
}
//anyways, even if i create new ListBox lb = listBox1 in ServerFunction(..), it throws System.InvalidOperationException => Access attempt to listBox1 not from thread where is was created.
我做错了什么?我认为创建静态控件是解决此问题的最终问题,但即使这样也无法工作......
答案 0 :(得分:2)
如果我没记错,为了从另一个线程更新UI,你需要使用这个调用:
this.Invoke((MethodInvoker)delegate
{
MethodForUpdatingUI();
});
这将从UI线程启动MethodForUpdatingUI()
,使您可以访问控件。
因此,要在代码中使用它,我会尝试更改IncomingDataClass_SomeEvent
:
void IncomingDataClass_SomeEvent(object sender, EventArgs e, string ex_data)
{
this.Invoke((MethodInvoker)delegate
{
UpdateListBox(ex_data);
});
}
UpdateListBox(string ex_data)
{
if (ex_data.Contains("listbox"))
{
ex_data = ex_data.Remove(ex_data.IndexOf("listbox"), "listbox".Length);
listBox1.Items.Add(ex_data);
}
}
如果不是你要求的情况,请随时纠正我,否则这是一个不好的实践。我没有测试过代码。
答案 1 :(得分:0)
您只能从UI线程处理UI控件。如果那些控制是静态的,那么无关紧要。使用Dispatcher对象或SynchronizationContext对象来修改来自不同线程的控件。