2011-08-28 62 views
7

我有一个服务器类,它基本上等待来自客户端的连接。在该类中,我创建了一个NetworkStream对象,以便能够从客户端接收字节。因为NetworkStream.Read()方法不是异步的(意味着它将等待,直到它从客户端读取字节以继续执行类似于messagebox方法的代码),那么我必须读取单独线程中的字节,以便如果程序碰巧等待读取数据,则使用程序的用户仍然可以与程序交互。来自不同线程的访问对象

反正很多对象都属于该线程。一个例子是我有一个名为日志的List。我使用该列表来了解服务器的状态。也许它正在监听连接,或者它的状态是“连接”或“断开”。

所以,如果我这样做:

Server myServer = new Server("192.168.0.120","1300"...\\ I pass the appropite parameters in order to instantiate it 

//... 
.. then I am able to latter look at the log as 
string foo = myServer.Log[0] for example. 

,因为我想知道当日志被更新,服务器类我已经创建了一个事件为:

public delegate void onUpdateHandler(string newStatus); 
    public event onUpdateHandler onUpdate = delegate { }; 

然后我火事件在服务器类为:

onUpdate("waitingForConnection"); 

和我收到这些事件与方法:

enter image description here

但如果我尝试做一些NEWSTATUS我得到的错误,指出:

System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it. 

所以我怎么能传递一个对象与事件?


编辑

,所以我也注意到,如果我这样做:

enter image description here

我也得到一个错误!

但是当我做呼叫从一个按钮,同样的事情:

// SERVER IS RUNNING BEFORE CALLING THIS METHOD 
    private void button3_Click(object sender, RoutedEventArgs e) 
    { 

     listView1.Items.Add("my own string"); 

    } 

我没有得到一个错误!

为什么我在事件中遇到错误,并且在用常规按钮调用时没有遇到错误。

回答

12

的问题是,该线程试图访问ListView控件这是一个DependencyObject具有线程关联,使用Dispatcher到UI线程上执行这样的方法,如:

Application.Current.Dispatcher.Invoke((Action)(() => 
{ 
    listView1.Items.Add(newStatus); 
})); 

另请参见threading model reference获取更多信息。

+0

我的方法我得到一个错误,指出:不能转换lambda表达式键入'System.Delegate',因为它不是一个委托类型 –

+0

@TonoNam:哦,是的,你需要投它,或明确创建一个行动。 –

+0

@Tono,lambda必须被铸造成某种代表类型,请参阅我的编辑。 – svick

1

问题不在于您尝试使用您发送给该方法的值进行操作,而是您尝试使用该方法的问题。

事件处理程序仍在后台线程中运行,并且从那里您不能使用任何UI控件,因为它们属于主线程。

处理的常用方法是使用CheckAccess方法来检查,如果你需要切换踏板,以及Invoke方法来交班工作,主线程:当我把里面

void server_onUpdate(string newStatus) { 
    if (!listView1.Dispatcher.CheckAccess()) { 
    listView1.Dispatcher.Invoke(server_onUpdate, newStatus) 
    } else { 
    listView1.Items.Add(newStatus); 
    } 
} 
+0

根据标签,这不是WinForms ... –

+0

@ H.B .:我已经纠正了这一点。 – Guffa

+0

@Guffa很好的解释谢谢 –