Best Practices? Wait until receive or raise an event on receive - c#

First of all, I wanted to thank the community. You've been of great support lately ! Usually i don't even need to ask the questions because they're already there. Now i have an issue that's not directly related to code but programming itself.
I'm working with a FTDI Chip and C# programming a communication protocol in which a PC application acts like the Master (will send requests) and there is also Slave device who will answer to them, not immediately, maybe a couple of millisecs, but anyway, will take some time. I'm stuck in a conceptual/philosophical code design question.
After sending a request, should I ask right away for an answer (checking also a timeout) or should I constantly monitor the input (BackgroundWorker powered) and raise an event after receiving a data input ? What would you recommend, what is on your experience. What factors should i consider for making my choice ?
I never studied software design of programming itself so i think i lack the basic on this, but this is a personal project i'm working on and sure i'd love some feedback/pointers on this from you guys.
Thanks !

My preferred solution in this scenario would be to issue the request in async mode (such that you get called back by an event that fires when it completes), and also implement an async time out using standard .Net mechanisms, which calls you back if it appears the slave is unresponsive. This way you just start the request and the timer and then can continue doing more work, without needing any other threads to process results.
You would have to make sure that concurrent time out and response arrival is handled cleanly using a locking mechanism, so that you know for sure whether you are timing out or handling the response.
Try to avoid polling and input monitoring, unless your slave's API does not allow for deterministic generation of response events.

Normally i would work with the asynchronous approach on the low level site and maybe put some synchronization mechanism on top of this. Here is some example approach if you get data fragments and you have to put these fragments together to a whole message.
So on the low level site implement a BackgroundWorker that checks constantly for incoming data and raise some kind of event if you got something and put this into the event.
Above this is someone listening to the events of incoming data and puts all this (maybe) fragments into an internal queue. There it checks if it already has a enough data for a complete message, maybe does some error checking, etc. If it has a complete message it will raise an event to send this message to all listeners out there.
On top of this put another class that watches for messages and reacts on them. This class maybe implements some sync mechanism to watch out if an incoming message matches to something that should happened beforehand.
I think this design makes it easier to react on data that comes in when you don't expect something. And when you like to shutdown you don't have to wait for any timeouts to happen (maybe a very small one the low level BackgroundWorker is using to pull the data out of the source that doesn't support an event mechanism).

Related

Application Insights Telemetry: can you track traces/events/etc. asynchronously?

I am a longtime user of Azure's Application Insights, and I use the TelemetryClient's TrackTrace() and TrackException() liberally in every enterprise application I write.
One thing that has always bothered me slightly is that these methods are synchronous. Since these methods communicate with an external API, it would seem there is an ever-present risk of blocking; e.g., if the network is down/slow, or if App Insights' own API is having issues.
In such cases, it seems possible (at least in theory) that an entire application could hang. In such cases, if they ever occur, I would like my applications to continue operating despite failing to trace within a reasonable time frame.
I've done some research online, and it appears that there is no built-in way to call these methods asynchronously. Do you know of any way to accomplish this? (Or.....does the App Insights API have an under-the-hood black-box way of automatically preventing these sorts of things?)
Of course, I know I could always wrap my calls in a Task (e.g., await Task.Run(() => myTelemetryClient.TrackTrace("my message")); (or write an async extension method that does this). I could also use a timer to cancel such a request. But it would be nice if there was a more integrated way of doing this.
Can anyone enlighten me? Is this really a potential problem that I should be concerned with? Or am I merely tilting at windmills?
Update: I just now saw this, which indicates that AI does indeed handle tracking in an asynchronous manner "under the hood". But how can this be reliable, given the truism that asynchronous operations really need to be made async all the way up and down the call stack in order to be blocking-proof?
Is this really a potential problem that I should be concerned with?
No. None of the TrackABC() methods communicate with any external API or do anything which would take a long time. Track() runs all telemetry initializers, and then queues the item into an in-memory queue.
While the built-in telemetry initializers are designed to finish quickly and make no I/O or HttpCalls, if a user adds a telemetryinitializer which makes an http call or something similar, then Yes, it'll affect you Track() calls. But with normal usage of TelemetryInitializers, this should not be a concern.
If it's anything like the JS API, the tracking events are placed in a queue then dequeued and sent (possibly in batches at configurable intervals) independently of the TrackXXX methods. Enqueuing an event can be synchronous, but the sending end of the process can operated asynchronously. The queue decouples the two from one another. –
spender
I think #spender answered my question! Thanks!

Socket ReceiveAsync, Timeouts and Questions

I need to reimplement a database connection driver for some legacy cobol database for one of my customers. The way the application is built, i cannot use async/await (just leave it like that, i know it is stupid).
The whole application is an ASP.NET API.
The old driver uses a c++ dll, that is included with inter-op methods. The idea behind the old system is: use one connection to the db for everything, have multiple threads send a packet and have one thread that receives the answers and delegates them to the right thread.
To keep the connection alive, one needs to send some sort of ping message to database and handle its pong message.
I reimplemented that as POC in c#, have one connection, open a background thread and use AutoResetEvents to notify the right threads that the answer is ready to be processed. I set the ReceiveTimeout to 5 seconds, and while there was nobody sending data to the server, the receive timeout helped me to send the ping-message to the server.
A reason for the rewrite is, that the one-connection-solution does not scale.
So, my idea is to use a socket pool and ReceiveAsync with SocketAsyncEventArgs on the sockets.
The solution works so far, but not really good. Here are some questions:
As ReceiveTimeout is not compatible with ReceiveAsync, is there a other way then a timer to send my ping-messages
when using ReceiveAsync, can i still use normal Send to send data, or do i have to use SendAsync?
when ReceiveAsync does not receive all required data, may i use Receive to read the rest of it, or is it better to use ReceiveAsync again for the missing data?
Maybe not relevant: I use Artillery to fire some performance tests on the new driver; from time to time they timeout after 30 seconds (thats the db-transaction timeout i set); when i try to debug that Artillery gets ESOCKETTIMEDOUT even though no breakpoint is hit - is this a known behaviour when debugging an IIS process under load?
use AutoResetEvents to notify the right threads that the answer is ready to be processed.
May I suggest a thread-safe queue? BlockingCollection<T> or BufferBlock<T>?
I set the ReceiveTimeout to 5 seconds, and while there was nobody sending data to the server, the receive timeout helped me to send the ping-message to the server.
This is weird. I assume the entire protocol is ping-pong based, or else using a receive timeout to send messages would not work.
my idea is to use a socket pool and ReceiveAsync with SocketAsyncEventArgs on the sockets
If you can't use async/await, I would advise switching to the Begin*/End* style of asynchronous API. Going straight from synchronous to SocketAsyncEventArgs is quite a leap; SocketAsyncEventArgs is the most difficult form of socket async programming.
is there a other way then a timer to send my ping-messages
I would recommend a timer; that's the normal solution for heartbeat messages. The desired semantics should be "we want to send data at least this often". So use a timer that you can reset when sending regular messages (not receiving messages).
when using ReceiveAsync, can i still use normal Send to send data, or do i have to use SendAsync?
You should be able to use synchronous for one stream and asynchronous for the other. I've never tried this, though; all systems I've worked on are fully asynchronous.
when ReceiveAsync does not receive all required data, may i use Receive to read the rest of it, or is it better to use ReceiveAsync again for the missing data?
This question doesn't make as much sense to me. If you're asynchronously reading, you shouldn't block the calling thread.
Also, I think this question is framed from the wrong perspective. It seems like the code wants to "receive the next message", but this is a problematic way to approach reading from a socket. Instead, I recommend that your code have a loop that endlessly reads from the socket and passes that data to another type that buffers it as necessary and pushes out messages as they finish.
is this a known behaviour when debugging an IIS process under load?
I would not expect so, but I don't have much IIS load testing experience.

Event trigger - Best practices

My program collects data from various sensors and whenever there is something wrong with the sensor reading, then I have to send an email to alert the user.
For this, I have assigned a variable SEND_MSG to trigger the email send event. Whenever there is something off with the reading, I set SEND_MSG to 999 and another thread, which loops and checks this variable triggers the send email process. Read/Write operation of the SEND_MSG occurs inside a lock statement.
Is there a better way to do this?
Thank you.
You are polling a variable holding status from a thread to communicate state. That's not a very efficient design.
There are a number of inter-thread communication mechanisms that handle this situation much more elegantly.
For a great overview of mechanisms see http://www.albahari.com/threading/
If you simply want to communicate the need to send an email, you can use for example an AutoResetEvent.
Another option, which makes it easy to communicate additional information such as the sensor number, type of malfunction, etc., you can consider using a BlockingCollection. There's a good example of how to use it at the bottom of that link.

0MQ windows GUI best practice

I've a pretty simple question/issue. I want to use 0MQ for some pretty basic Pub/sub functionality. My subscriber app is a windows GUI based app using plain winforms.
As there seems to be no explicit reference in 0MQ for handling this scenario, I am assuming that worst case I'd have to use a BeginInvoke(...) on the windows GUI thread once the 0MQ thread has recieved any subscription message. This seems pretty straightforward but if anyone has any insight/opinion/heads up in terms of the best way to handle this I'd very much appreciate it.
Thanks in advance
David
For your ZeroMQ subscriber in a WinForms application you have at least a few options:
Use a background worker thread to receive your 0MQ message. When you receive a message pass it to your background worker progressChanged event to update your UI.
Use a system thread to receive the message and invoke to update your UI.
Another suggestion on SO also suggest using a system thread to queue the message upon receive and a timer event to dequeue the message. If you used a Forms Timer you could update the UI without invoking or if System Timer you would need an invoke.
Which method you choose depends on your design criteria.
As pointed out, there are several ways to hook up ZeroMq into a WinForms app. It really does not differ much from using ZeroMq and C# in other settings, like in a console application. The main difference is as you point out that you have to get the messages into the Gui thread in order to update your Gui controls.
An example of using a separate thread + queues (producer/consumer pattern) can be found here: Examples of zeromq pub/sub with C# winform
Another way could be to use (again) a separate thread to do the ZeroMq work and set up an event that gets fired each time a message is received. The Gui could then hook up an event handler and process the message. You would of course also have to invoke any updates to the Gui. A drawback to this approach is that the event processing will interfere with the ZeroMq handler thread a bit, especially if the Gui updates takes a while, and if you receive lots of data.
All solutions have their pros and cons, it all depends on how your particular problem domain looks. All-in-all, integrating ZeroMq into a C# application, be it WinForms or other, is IMO pretty straightforward. The clrzmq wrapper is well-written and easy to use. The problems you may run into has more to do with the limited error feedback in ZeroMq itself. If you encounter strange crashes; try to run the same logic in a console application, that will give you better error messages.

Error handling patterns for multithreaded apps using WF?

I was writing up a long, detailed question, but just scrapped it in favor of a simpler question that I didn't find an answer to here.
Brief app description:
I have a WPF app that spawns several threads, and each thread executes its own WF. What are some of the best ways to handle errors in the threads and WF that will allow user interaction from the GUI side? I definitely plan to handle any low level exceptions in the thread, because I don't want the thread to exit.
Summary of questions:
How have you implemented communication between WF and the thread that starts it? There is WorkflowTerminated, but I don't want the workflow to exit -- I need to fix the problem and let it continue. I assume the only option is using a FaultHandler, but was wondering if there's another way to do it without using an activity block. I am hoping there's a framework out there that I just haven't found yet.
The error from WF needs to get caught by the thread, which then needs to display the error in the GUI. The user will then make a logical choice for recovery, which should then be sent back to the thread, and then to WF. Again, is there something existing out there that I should take a look at?
Even buzzwords / keywords that accomplish what I am describing would be really helpful, and I can do the legwork on researching each of them. However, any additional insight is always welcome. :)
What's worked for me in multi-threaded WPF apps is to have the errant thread invoke a callback method that passes the exception and other info back to the UI thread. Callbacks can have return values, so if your thread can block while waiting for the user to respond, then that can work for you. Remember that the callback will run on the thread that calls it, so any UI updates have to be done via the control's dispatcher. You will have to decide whether all of the threads use the same callback and what kind of synchronization you'll need if there's a chance that multiple threads can throw exceptions simultaneously.
Here's how I ended up solving this problem. But first a little background info:
User clicks a button in the GUI that causes the candy packager to start running. This is done via a command binding in the ViewModel, which then calls a low-level function in the Model. The function in the model launches a thread and executes a state machine.
At some point, the machine will fail. When it does, I compile information about the error and possible (known) recovery methods. I put this into an object and then pass it to the GUI via a callback interface. In the meantime, the worker thread is stuck waiting for an Event to get set.
Eventually, the candy worker will notice the error and will click a button telling the system what to do. This results in two things: 1) it flags one of the recovery methods as the preferred one, and 2) sets the event. Now the worker thread continues on, checks for the preferred error recovery method and transitions into the respective state in the state machine.
This works very well (so far). The part I know is totally lame is the manner in which it checks for the preferred error recovery method. I am essentially setting a string variable, and then comparing this string to a list of known strings. Ultra lame, but I'm not sure of a better way to do this, other than using an enum. Does anyone have recommendations for me?

Categories

Resources