Async TCP Data from another thread cannot be safe. Cross-Thread Operation
I have two class libraries. One is a normal .NET assembly and the other is a Compact Framework device assembly linkings the desktop class files. This library is responsible on TCP Async operations between a server and client.
Now i create a Windows project for the server and a Windows Mobile Forms device project as a client.
I use som开发者_JS百科e events on Data Received for the client and the server. To fire the data came from the ASync received data through TCP safe I use a Control class dummy to check if Invoke is required.
The strange thing is that when sending data from server to a device CF client the data not need any thread handling for the controls where you need to show the data. But sending data from a client to a server I get cross thread operation exception.
Here is some code.
The static method i use to safe the data.
public static void InvokeIfNecessary(Control control, Action setValue)
{
if (control.InvokeRequired)
{
control.Invoke(setValue);
}
else
{
setValue();
}
}
When I want to throw data came from the TCP communication.
if (OnClientChangeConnection != null) SafeData.InvokeIfNecessary(_helpControl, () => OnClientChangeConnection(ConnectedClients, requestClientInfo));
Any idea why I get this behavior? Or any better handling this problem ?
Thank you!
Since you are defining InvokeIfNecessary
, notice the "if necessary" part. This means that the request may come in on a different thread from the dispatcher. Notice I say "may" -- which means that it may not, and so may come from the dispatcher.
The full framework and the compact framework may use threading differently to handle async operations. For example, the compact framework may be single-threaded (since it runs on Mobile) while the server full framework may be multi-threaded. The API looks the same, but data may come in from different threads.
One good example is Silverlight, which uses the dispatcher thread (i.e. the main UI thread) to do network access and stuff, even though you are using the BeginXXX/EndXXX async calls. Therefore, if you run simplistic code on this mobile environment, you won't get a thread exception, but you definitely may get one on the server, where the BeginXXX/EndXXX calls may go to different threads -- again they may not, and it really depends on the server's decision at the time of the call.
Therefore, you always need to find out whether a request may come from a different thread. Using something like your InvokeIfNecessary
is a necessary evil and is the right thing to do -- don't omit it just because in some environments you don't see the problem.
精彩评论