Currently I am about to develop logging for a c# application into a SQL server table.
I have a designated class called Logger that has a static method writeToLog().
I just want to call that static function without block the calling thread.
How is this possible in C# clean and fast?
The functions don't return anything they are just fire and forget.
Thanks for you advice
There is the chance that the serveral available logging libraries out there have spent some thoughts about performance.
If you still need to develop a light weight solution yourself I think of two ways.
1.) Create a Task that runs the logging function, without awaiting them
2.) The Log-Method saves the Log-Information in a queue that is written to the SQL-database with a background thread.
I would recommend the second way, because the logging itself can be done in a synchronous function call without the Task creation overhead.
Another argument for this approach is that it is possible to gurantee the order of log messages. By using a Task for each single message the order of execution is not defined.
And a last argument: It might be more performant to write blocks of messages to the SQL table. By using the queue you will be able write messages in a bulk operation.
Related
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!
I found this related question but my situation is a little bit different.
I have a ASP.NET application that produces long running tasks that should be processed by a number of background processes (Windows Services). Most of the tasks are similar and can be handled by most task runners. Due to different versions of the client application (where the tasks are generated by users) some tasks can only be processed by task runners of specific version. The web server has no knowledge about the kind of task. It just sends all the tasks to the same queue using MSMQ.
If a task enters the queue, the next free task runner should receive the task, decide if he can handle this kind of task, remove the task from the queue and run the task.
If the runner that received the message is not able to process this kind of task, it should put back the message to the queue, so that another runner can have a look on the message.
I tried to implement a conditional receive using a transaction, that I can abort if the task has the wrong format:
transaction.Begin();
var msg = queue.Receive(TimeSpan.FromSeconds(1000), transaction);
if (CanHandle(msg))
{
transaction.Commit();
// handle
}
else
{
transaction.Abort();
}
It seems to work, but I don't know if this is the preferable way do go.
Another problem with this solution is, if there is no other free runner that can handle this message I will receive it again and again.
Is there a way I can solve this problem only using MSMQ? The whole task data is already stored in a SQL database. The task runner accesses the task data over a HTTP API (Thats why I rule out solution like SQLServer Service Broker). The data sent to the message queue is only meta data used to identify the job.
If plain MSMQ is not the right tool, can I solve the problem using MassTransit (I didn't like the fact that I have to install and run the additional MassTransit RuntimeServices + SQL db for it) for example? Other suggestions?
The way you are utilizing MSMQ is really circumventing some of the fundamental features of the technology. If queue message cannot be universally handled by the reader, you are incurring a pretty sizable system performance penalty, where many of your task processing services can get sent back empty-handed when they ask for tasks. In extreme scenario, imagine what would happen if there were only one service that could perform task type "A." If that service were to go down, and the first task to be pulled out of the queue is of type "A," then your entire system will shut down.
I would suggest one of two approaches:
Utilize multiple queues, as in one per task version. Hide task retrieval behind an API or some other service. Your service can request a task from one or more task types, or you can even allow for anything. The API would then be charged with figuring out which queue to pull from (i.e. map to a specific task type, pick one at random, do some sort of round robining, etc.)
Opt for a different storage technology over queueing. If you write good enough SQL, a relational database would be more than up for the task. You just must exhibit a lot of care to not incur deadlocks.
Can you create another queue? if Yes then I would create multiple queues. Like GenericTaskQ, which will have all the tasks in it then xTaskQ and yTaskQ. Now your xTaskRunner will pick the tasks from Generic queue and if can not process it then put it in yTaskQ(or whatever q is appropriate). same is for yTaskRunner, if it cant handle the message put it in xTaskQueue. And x and y taskrunners should always look for their respective queues first, if nothing there then go look into genericq.
If you can not create multiple qs, use message(task) labels (which should be unique, we normaly use GUID) to remember what tasks have already been seen by a task runner and can not be processed. also use Peek, to check if this message is already been addressed, before actually receiving the message.
Hello i want to use the State Machine Compiler (SMC) with C#
http://smc.sourceforge.net/
i have created the sm-File to describe the state machine and generated c# code from it.
Then i created my own class MyClass,add the generated class which was generated with smc and implement the methods.
My Problem is how can i run this statemachine? With a While-loop, a async call or the Task Library ? What is an elegant way?
The Statemachine is a behaivior for sending data throught the serialport. So that the user can call MyClass.Send(Data) and the StateMachine should work behind the curtains.
Can someone give me an example how to use the statemachine in own code?
Regards
rubiktubik
I've used SMC in many application and I was very satisfied with it. I hit the same problem as you. SMC generates code for C# which is synchronous and linear. This means if you issue a transaction by calling fsm.YourTransaction() and by chance somewhere in the middle of that transaction you issue another transaction, it would be directly called. It is very dangerous, because it breaks the base principle of a state machine - that transactions are atomic and the system is guaranteed to be in single state, or single transition all the time.
When I realized this hidden problem I implemented an asynchronous layer above the state machine code generated by SMC. Unfortunately I cannot provide you with the code, because is licensed, but I can describe the principle here.
I replaced direct method calls with asynchronous event processing: there is a queue awaiting transactions. Transactions are represented by strings, which must be the same as transaction methods in fsm. They are removed from the queue one by one in an independent thread. Transaction string is transformed to a fsm method call.
This concept proved to work very well in many critical applications. It is rather simple to implement and easy to extend with new features.
Final form of this asynchronous layer had these additional features:
Perfect logging: all transactions and their arguments, time of arrival, time of processing ...etc.
Possibility to replace the independent thread with an external thread - sometimes it is better to process things in thread provided from outside (Windows GUI is very sensitive to external thread calls...)
Preprocessing of transactions - sometimes the system was expected to change state only if a sequence of transaction occured. It is rather clumsy to achieve it directly with SMC. I implemented so called "transaction transformations" - it was possible to declare how a set of transactions is transformed into a single transaction.
I'm dealing with a hardware resource that can only handle 1 command at a time. I'm going to exposing some of it's API functions via a web interface, so obviously there's a good chance more than 1 command will get sent at a time. I have decided that queuing these commands when they're submitted is the best way to ensure serial processing.
I'm planning on implementing the queue in a static class. The web app code-behind will add a command by calling a method corresponding to the command they want. I want the calling method to wait until it gets the output of its command, so no async magic is required.
Am I doing this right? Is there a better way?
How do I start implementing the queue in C# (I usually work with Java)? I assume I'll need some sort Event to signal a job has been added, and a Handler to initiate processing of the queue...
I'm using .NET Framework 4.
You can use the ConcurrentQueue class for your implementation and have a dedicated thread to process items in the queue.
For the waiting part you can use an AutoResetEvent, producers pass the event instance to the singleton class along with the request, then calls WaitOne() which blocks until the processor has signaled processing is completed by calling Set().
Sounds like a good approach EXCEPT: Use the Generic Queue collections class. Do not write your own! You would be reinventing a well-built wheel.
We have C# application that crawling and executing code. But some time system stolp responding becouse code executing too long. How can we stop executing code after 10s that application will not stop responding any more.
The approaches taken to tackle this problem are dependent on the way you've designed your long running operation. So, without further details, I can only provide general pointers.
If your code takes to long to execute because you're not getting a response from a remote system (ie. db, website, etc) in time, then consider timeouts. If the API you use for making those remote calls, doesn't support timeouts, consider something like the CircuitBreaker pattern:
http://davybrion.com/blog/2009/07/protecting-your-application-from-remote-problems/
http://timross.wordpress.com/2008/02/10/implementing-the-circuit-breaker-pattern-in-c/
If it's simply that your application is doing a lot of work, make sure you do that work on a thread other than the UI thread, as Twitch said, to keep the UI responsive.
If you're using a very long loop doing internal work, then it could be worth checking repeatedly in that loop for a cancelation condition being met (this could be a flag set from a different thread or even elapsed time). This approach is called cooperative cancellation.
This article on the .Net 4.0 cancellation framework gives some good background, along with this article which it references.
You have to add some sort of way for the program to tell windows "no, it's not frozen, it's working", either by making all the processing and crawling in another thread, or by doing some form of notice, like printing something every few frames.
You can call Application.DoEvents to perform events while performing a long task in a GUI thread. That way it won't block the GUI.
You should consider running the long task in a thread itself though, since you get a lot more direct control then.