简体   繁体   中英

Multithreading strangeness

I'm developing a WCF client/server app and the client calls the server asynchronously by wrapping the call in Task.Factory.StartNew and using a continuation to call a user-supplied delegate on return from the WCF call. The server operation performs (amongst other things) some serial I/O before returning a response to the client. The service also utilises a BlockingCollection to enqueue these requests, ensuring that they are executed one at a time to avoid serial port contention. As it stands, the app runs perfectly fine, even when the client fires a load of requests to the server in quick succession.

Now, the app can also be configured to run in a "direct" mode, where the client directly references the server-side assemblies (for performance reasons, if client and server are on the same PC). In this scenario the client uses an instance of the service class (rather than a proxy created by ChannelFactory) and calls its operation method directly, using the same asynchronous Task.Factory.StartNew helper.

In this "direct" mode I'm finding that the server-side execution seems to run slowly (it misses serial port data), as though it is being interrupted in some way. I can "fix" it by changing the client-side task to use TaskCreationOptions.LongRunning . Unfortunately this then breaks the app when in "WCF mode", which seems to suffer the same slowness issues.

Now, I could simply include the TaskCreationOptions (or not) depending on which "mode" the app is using, but I would like to understand why this is happening in the first place. Any ideas?

Edit : I notice the problem during app startup when the client sends a dozen requests to the server one after the other, in a for loop. After this the client polls the server every half a second - this isn't affected by the problem, nor are the other couple of thread timers that run both client- and server-side (one of which fires every 65ms!). I came across an article stating that the threadpool will create new threads until the minimum number of threads is reached, after which it limits the number of threads being created to one per 500 milliseconds. This matches the symptoms of my problem as I'm seeing the slowness hit approx every half a second. I'm going to refactor my client-side code to avoid hitting the server so many times in quick succession, which is a shame. I really wanted to fire off all these requests one after the other, then handle the results in the callback delegates once they had been processed by the server. But with this threadpool "feature" it seems that I can't do this.

如果切换到LongRunning会解析它,这意味着当未设置LongRunning时,任务框架选择使用线程池,或者甚至根本不使用单独的线程。

You could run some performance tools or attach timers to find out where the bottlenecks are. Alternatively use the WCF mode over a named pipe. (http://msdn.microsoft.com/en-us/library/ms733769.aspx)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM