It's fine as long as the UI thread isn't overburdened by those invokes. It does introduce some latency to the communication, which usually isn't an issue, however, it can become more of a problem if you're doing a lot of Invoke
s, or if the UI thread is doing a lot of work (eg. rendering complex graphs or something like that). Invoke
is a synchronous method - it will not return until the invoked command is actually processed, and returns its return value.
As long as you're not tied up by these issues, all is well. Profiling and performance testing is critical to allocate your resources correctly, guessing is usually a huge waste of time and resources.
If you don't need the resulting value (or at least not synchronously) and you're starting to get into performance trouble, have a look at BeginInvoke
, which handles the invoking asynchronously. This means your networking thread doesn't have to wait for the UI thread to work. This is quite critical in high performance servers with thousands of connections. They simply can't afford to wait while the UI does its thing.
However, do note, that having a server socket running on a different thread is not a good solution for larger servers, and in fact, it's no longer the easiest solution either. .NET now has great support for asynchronous calls and callbacks, making implementations of asynchronous processing a breeze. In your typical Winforms application, it means that I/O blocking applications can work without having constantly running and polling threads. For example, waiting for a new connection can be as simple as:
var connection = await listener.AcceptTcpClientAsync();
That's it. Automagically, all the callbacks will be processed at the right time, without blocking the processing, all of your own code always running on the main UI thread. In other words, you can easily do this:
while (!aborted)
{
var connection = await listener.AcceptTcpClientAsync();
tbxLog.Text += "New connection!\r\n";
}
While this seems like an infinite loop blocking the UI thread indefinitely, the reality is that when the application gets to the await
keyword, it will register an asynchronous callback and returns. Only when the asynchronous callback is actually invoked (by IOCP in this case) is the code resumed (on the UI thread), and tbxLog
has the text appended, followed by waiting for another connection.