4

I have to write a TCP/IP client application in .NET. (The server is actually an embedded device, so not concerned about the server side of it.)

I am wondering, instead of using asynchronous socket client read/write calls to keep my main application responsive, why not just use a backgroundworker and use synchronous calls inside that background loop?

They would serve the same purpose, no, and easier to program and debug?

BTW, I am restricted to .NET 3.5 so cannot use the async/await calls, which from another thread here ( Async/await vs BackgroundWorker ) seems to be what everyone is suggesting to use instead.


Based the many helpful comments below, I realize that should have been a little more detailed in my OP above.

The embedded device is a Digi WiFi Module ( http://www.digi.com/products/wireless-wired-embedded-solutions/zigbee-rf-modules/point-multipoint-rfmodules/xbee-wi-fi#overview )

I am NOT sending and receiving at the same time. The embedded device is connected one of our data acquisition systems. The DAQ receives a command and sends out a reponse - ONLY ONE command/response at a time.

I send a command to the embedded device. I then wait for the response. If I get a response I process it and then send the next command. If I do not get a response within x seconds, then I send the same command again. If I do not get a reponse even after n tries, then I assume the connection is broken (ok to do it this way? Then show an error message and stop? close socket connection and reopen and try again a few times?)

So it is ok if my backgroundworker thread blocks while receiving/sending. It is either sending or receiving, not both.

Community
  • 1
  • 1
Soundar Rajan
  • 517
  • 2
  • 7
  • 17
  • if you stick with the background-worker you will *block* it's thread. If you do it async your app can scale way better. What's better just depends on your load and scenario. – Random Dev Aug 08 '14 at 14:48
  • Well, that's fine, much easier to reason through your code and fix the bugs, *very* important. Only shout-back you'd ever get about that is: do you *really* want to burn a thread-pool thread on receiving data over a socket? Your program will pretty much keel over when you try to keep 8 or 16 connections going. Buy better hardware to get 32 or 64. You can keep *ten thousand* connections going with the cheap hardware when you use APM. – Hans Passant Aug 10 '14 at 23:11

4 Answers4

2

I have to write a TCP/IP client application in .NET. (The server is actually an embedded device, so not concerned about the server side of it.)

First rule: try to level-up the protocol abstraction. WebSockets are infinitely preferable to raw TCP/IP.

If you absolutely must use TCP/IP (i.e., the embedded device is an off-the-shelf product and their tech support is unwilling to support WebSockets), then be sure to check out my TCP/IP .NET Sockets FAQ.

I am wondering, instead of using asynchronous socket client read/write calls to keep my main application responsive, why not just use a backgroundworker and use synchronous calls inside that background loop?

Depends on how reliable your app needs to be. 24x7 reliable systems (e.g., industrial automation, one of my areas of expertise) definitely prefer asynchronous TCP/IP. It's possible to do it with threads/BGWs, but note that you would need two threads per connection, not one. This is due to the fact that you need to be always reading as well as periodically writing.

There are tons of "simple" examples (I'm looking at you, MSDN) where there's just an infinite loop that alternates reads and writes. But those are just not a realistic approach for any reliable software.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
1

I never used BackgroundWorker and I hate it. Let's forget about it and assume it is a worker thread.

They would serve the same purpose, no, and easier to program and debug?

You're overlooking the asynchronous API s, for a true asynchronous method there is no thread behind it. Socket's BeginXXX and EndXXX are based on IOCP. So you're not wasting any resources by using asynchronous methods.

In the worker thread case you're wasting a thread(1mb of stack, cpu resource) which is not a good idea. If an operation is inherently asynchronous, then waiting for it synchronously is wasting the resource.

Prefer asynchronous methods over synchronous.

Also I don't understand how asynchronous methods makes debugging difficult.

Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • 1
    oh debuging async. behaviour (or even undertanding it correctly) **is** one of the biggest problems nowadays isn't it? – Random Dev Aug 08 '14 at 15:03
  • 1
    @CarstenKönig I guess both are two different topics. Once you understood asynchronous methods, It will be easy to debug. Isn't it? Without understanding them, trying to debug is like *trying to run when you don't know how to walk.* – Sriram Sakthivel Aug 08 '14 at 15:11
1

There is nothing wrong with using synchronous socket IO. All it costs you is 1MB of stack memory. If you are willing to expend that amount (and it is a small amount), and productivity is important to you, go synchronous.

I have written about that before. Weigh the pros and cons. Async is all the rage these days. You pretty much won't find anyone on Stack Overflow recommending synchronous code anymore. I feel the trade-off often is not being made in a rational way.

Community
  • 1
  • 1
usr
  • 168,620
  • 35
  • 240
  • 369
1

I'm going to elaborate on what others are saying and suggest using the Begin/End methods. Using another thread will probably achieve the same functionality, but why reinvent the wheel when you can use what's already built in to the Framework?

My personal experience with Begin/End operations on sockets has been nothing but good. I find it so much easier to use than blocking calls because I don't have to worry about keeping the application responsive - .NET takes care of that for me. There is of course more setup work involved, but I think it scales much better than if you were to use blocking calls. I also don't see how Begin/End should give you more trouble than using the blocking versions of those calls.

Another thing about the background thread approach you should think about - and I have to wonder since you didn't specify - how are you planning on handling sends AND receives on the same background thread when either call will block that thread? You'd have to have two background threads running unless your application/protocols are designed in such a specific way that you will know exactly when the application should be sending and when it should be receiving. And even then, with a single thread you'd be limited to one of those operations at a time (since they'll block).

E. Moffat
  • 3,165
  • 1
  • 21
  • 34
  • 1
    +1. Though I must say that the attraction of synchronous methods is cleaner code; `Begin`/`End` forces a continuation passing style that can quickly become awkward. I would +1 you again if I could for pointing out that sends and receives are independent - this is the *massive* drawback to synchronous socket methods that is often overlooked until it is too late... – Stephen Cleary Aug 08 '14 at 17:14