SQLite is not asynchronous, and the exposed Microsoft.Data.Sqlite ADO.net *Async methods are implemented synchronously under the hood.
My question: how would you use SQLite in a asp.net core 5 API project which could benefit from asynchronous code, and also the async/await keywords to coordinate it?
I see two options
use the "fake" *Async methods, and lose the benefits of asynchronous code for the code parts that touch the db. If I understand correctly, in .net core blocking a thread will not lead to deadlocks (https://blog.stephencleary.com/2017/03/aspnetcore-synchronization-context.html). If I understand correctly that would act like synchronous code executing on a thread pool thread, with the added overhead of the async/await machinery.
write synchronous code only, and lose the benefits for parts of the code
Which one do you think would be better?
Thanks!
I would tend to use the synchronous Async methods, but it's not a strong preference. The only reason I'd prefer Async is just in case either a different database is used in the future, or SQLite gets real asynchronous methods in a future release.
What you definitely want to avoid is await Task.Run.
Related
I'm working on a project with an API running in the JVM and a JS client to access this API from the browser. The data classes of those objects which are converted to/from JSON are in a multiplatform module so that I can reuse the code on both platforms and don't accidentally end up with mismatched attributes. At this point it would be nice to also have the APIs interface in this mutliplatform module which then would be implemented and hosted in the JVM and implemented and presented in the browser. However, all methods of this interface need to be suspending in the browser since requests are (at least with Ktor's client, which I'm using) while they do not need to be suspending in the JVM.
Is there a good reason against having all those methods suspending even though I don't make use of it in the JVM? I know that methods usually should be suspending only if it's actually needed, but then I would be writing all the same interfaces (besides the suspend keyword) twice which seems like a lot of unnecessary boilerplate code to me. The methods which would unnecessarily be marked as suspending are called from suspending contexts (I'm using Ktor in the JVM too) so restricted usage wouldn't be a problem.
This seems like a matter of preference, really. Both using suspend and not using it have disadvantges, so you have to choose which weigh less.
From what you write, it seems that the advantages of using suspend (write code only once) outweigh the disavantage of polluting the interface with an unnecessary modifier. I am not aware of the possible runtime overheads here. Personally, I would opt to go with suspend.
The methods which would unnecessarily be marked as suspending are called from suspending contexts (I'm using Ktor in the JVM too) so restricted usage wouldn't be a problem.
This is the key point: the biggest hassle of the unnecessary suspend is having to launch a coroutine. If you're already inside a coroutine, the overhead of just one function along the call path being unnecessarily suspend is very low: a single extra object allocated per call.
While it's true that with having one interface you avoid boilerplate and you get the hassle of having to launch a coroutine on JVM, I'd consider another perspective:
When designing your abstraction IMO you shouldn't get much into implementation details, instead of thinking how jvm and/or js handles communication with the api I'd go with the question "Do I want to leave room for the platforms to handle this communication in an async/suspend way?". I believe this way you'll arrive to a more scalable solution, but true you'll lose out on some of the micro-optimizations
I have read a LOT of material about Windows Form projects not supporting MTA. I get it. However, I also have read about Background worker, async/await and BeginInvoke use with such solutions. This and this are just a couple of examples. Here's one that even uses MSMQ. Some of the examples I have reviewed go way back to VB6 days.
I need to augment a Windows Form project with code to interact with a vendor service via API calls that could benefit from async capability. This being 2014, what is the best way to approach this? I use VB NET and have VS 2010 for my development.
Ideally, I would like to create a class library with the logic to interact with the vendor and just return the results to my Windows Form project. Can that be done?
The fact that MTA is not supported doesn't mean that you can't use multiple threads. The MTA model is just one way to use multiple threads, but because it's difficult to implement objects for that model, Windows Form uses the STA model instead.
The important effect of this is just that it means that the main thread in the application takes care of everything that has to do with the user interface. You can start as many threads as you like/need, but whenever anything from those threads needs to be displayed in the user interface, they have to use the Invoke method to let that update be done in the main thread.
There are already asynchronous method in the framework, for example the BeginRead and BeginWrite methods in the System.IO.FileStream class. You can have a look at those for some hints on how asynchronous methods are used in the framework.
If the API is synchronous, you would make asynchronous methods by simply starting a new thread that does the API call and then executes a callback method when it is done. As it's that thread that is waiting for the response, the call doesn't occupy the main thread.
Is there a way around using the Invoke and InvokeRequired methods for objects which were created in other threads? Is there a method which is more direct and less memory intensive? Perhaps a state machine or thread controls?
Am I wasting my time worrying about this method's resource usage?
I'm using this invoke method: http://tech.xster.net/tips/invoke-ui-changes-across-threads-on-vb-net/
I'm using VB.NET in VS 2012
This strongly fits my doctor's usual advice: "if it hurts then don't do it".
There are several .NET patterns that emphasize keeping the threaded code separate from code that needs to run on the UI. BackgroundWorker has been available for a long time, note how its ProgressChanged and RunWorkerCompleted events run on the UI thread. Good place to update UI without having to invoke yourself.
The .NET 4 Task class hands you the TaskScheduler.FromCurrentSynchronizationContext() method. Which is a good way to chain a task that runs on the UI thread, pretty specifically intended to update the UI with the results of previous tasks that run asynchronously. VS2012 provides yet another weapon with the Async and Await keywords. All good ways to avoid writing the code you don't want to write.
My iPad app syncs with an XML feed, running the sync in an NSOperation subclass executed from an NSOperationQueue. As it parses the feed, it calls back to the main thread via performSelectorOnMainThread:withObject:waitUntilDone: to update various parts of the UI, schedule downloads, etc. Some of this is pretty expensive; the UI can sometimes become unresponsive for a second or two as a sync is going on.
To make the UI more responsive, I've removed the use of performSelectorOnMainThread:withObject:waitUntilDone: in favor of direct calls to perform all the sync-related tasks, including updating the UI. So now the sync takes place entirely on the background thread created by the NSOperationQueue. This seems to work pretty well, and the UI is much more responsive during a sync.
However, I'm leery of releasing with it this way. I've seen some mentions in various places that one should only update the UI on the main thread (example with reference to AppKit). But I've been unable to find anything specific on this topic in the documentation.
So how important is it to update the UI on the main thread? Which parts of an app are thread-safe and which are not? Is there perhaps a reference explaining what's safe to execute in an NSOperation and what should be executed only on the main thread in iOS? Am I really doing something unsafe or crash-prone?
It is extremely important that you always update the UI on the main thread. Touching the UI from a background thread can cause all sorts of issues, including corruption of internal state, crashes, or just plain incorrect behavior. Any work that doesn't require touching the UI should go ahead and do on the background thread, but the bits of code that update the UI definitely needs to happen on the main thread.
The Thread Safety Summary in the Threading Programming Guide discusses which Foundation classes are thread-safe and which aren't. The whole summary is worth a skim for quick answers to common questions.
The Thread Programming Guide also has a very brief section on Threads and Your User Interface, where “it is recommended that you receive user-related events and initiate interface updates from your application’s main thread,” and “Some frameworks, such as Cocoa, generally require this behavior.” No cross-reference to a discussion of this Cocoa requirement, but I imagine I'll run across it eventually.
But the upshot is that, according to this document it is important to perform UI updates on the main thread.
Are you sure you need the NSOperation? NSXMLParser.parse and NSURLConnection.start are already asynchronous. If the class that you're parsing updates some model object, and your view controller observes that model object using KVO, you might wind up with simpler, better performing code.
There is further documentation and discussion in a technical note that goes with the ListAdder sample code. It's TN2109: 'simple and reliable threading with NSOperation'. It repeatedly talks about only updating UIKit elements from the main thread and gives examples of correct and incorrect implementations. You might find further references to it by searching 'thread confinement'.
I have been using Spring.NET and NHibernate for some years and I am very satisfied. However, I was always playing around with multi threading, Reactive Extensions and eventually Task Parallel Library which is a great framework. Unfortunately all kind of multithreading approaches fail because of NHiberntate's session which is not thread safe.
I am asking you how can I benefit from parallel programming and still utilising NHibernate.
For instance: I have a CustomerRegistrationService class which method Register performs several tasks:
ICustumer customer = this.CreateCustomerAndAdresses(params);
this.CreateMembership(customer);
this.CreateGeoLookups(customer.Address);
this.SendWelcomeMail(customer);
The last two methods would be ideal candidates to run parallel, CreateGeoLookups calls some web services to determine geo locations of the customer's address and creates some new entities as well as updates the customer itself. SendWelcomMail does what it says.
Because CreateGeoLookups does use NHibernate (although through repository objects so NHibernate is acutally hidden via Interfaces/Dependency Inection) it won't work with Task.Factory.StarNew(...) or other Threading mechanisms.
My question is not to solve this very issue I have described but I would like to hear from you about NHibenrate, Spring.NET and parallel approaches.
Thank you very much
Max
In NH its the ISession that isn't thread-safe but the ISessionFactory is entirely thread-safe, easily supporting what it seems you are after. If you have designed your session-lifecycle-management (and the repositories that depend upon it) such that you assume one single consistent ISession across calls, then, yes, you will have this kind of trouble. But if you have designed your session-handling pattern to only assume a single ISessionFactory but not to make assumptions about ISession, then there is nothing inherently preventing you from interacting with NH in parallel.
Although you don't specifically mention your use case as being for the web, its important to take note that in web-centric use-cases (e.g., what is a pretty common case for Spring.NET users as well as many other NH-managing-frameworks), the often-used 'Session-Per-Request' pattern of ISession management (often referred to in Spring.NET as 'Open Session In View' or just 'OSIV') will NOT work and you will need to switch to a different duration of your ISession lifecycle. This is because (as the name suggests) the session-per-request/OSIV pattern makes the (now incorrect in your case) assumption that there is only a single ISession instance for the duration of each HttpRequest (and presumably you would want to be spawning these parallel NH calls all within the context of a single HttpRequest in the web use case).
Obviously in the non-web case where there's rarely a similar concept to session-per-request you wouldn't be as likely to run into this issue as session-lifecycle management is rarely as fine-grained/short-lived as it in web-based applications.
Hope this helps.
-Steve B.
This a difficult thing you ask for. The DTC has to be taken with care.
The only solution i may know is the use of reliable, transactional messaging (e.g. MSMQ + NServiceBus/MassTransit).
Such a design enables you to do this. It would look like this:
var customerUid=CreateCustomers();
Bus.Publish(new CustomerCreatedEvent() { CustomerUid = customerUid});
Then you could use two event handlers (Reactors) that handle the event and send an EMail or create the lookups.
This won´t allow you sharing the Transaction either but will ensure that the Reactors are run (in a new Transaction) when the creation of the customer suceeded.
Also this has nothing to do with the TPL.
Well thank you for answering. I know that the 'ISession that isn't thread-safe but the ISessionFactory is entirely thread-safe'. My problem in the above code for example is that the whole operation is wrapped in one transaction. So this.CreateCustomerAndAdresses(params) on main thread #1 will use for instance ISession #1 with transaction #1. Calling the other three in parallel will create three more threads and three more sessions and transactions which leads to database timeouts in my case. My assumption is that the transaction #1 is not successfully commited because it waits for the three concurrent tasks to complete. But the three concurrent tasks try to read from the database while a transaction is still active leading to deadlocks/timeouts.
So is there some way to tell the other threads/sessions not to create a new transaction but use the main transaction #1?
I am using the TxScopeTransactionManager from Spring.NET which utilises DTC (System.Transactions). I have googled that maybe System.Transactions.DependentTransaction could work but do not have a clue how to integrate it in my Spring.NET transaction managed scenario.
Thanks