There are certain places in my code where I invoke an activity using the WorkflowInvoker.Invoke method. I'm having a lot of performance issues because I create an activity every time I need to invoke this.
According this MSDN Blog post, I should cache the activity and run the same activity instance rather than creating a new one.
However, my application is multi-threaded. Would it be safe for many threads to use the same instance of the Activity? According to the MSDN documentation, it says its not thread-safe, but it looks like the standard message for almost all classes.
I suspect that it should be thread-safe, since the data that the activity uses is stored in a separate context (as Variables and Arguments) rather than a normal instance member of the activity class.
I have found no problems with threads sharing the same Activity instance. This makes sense because data is passed into the activity through the context (rather than the properties of the Activity object). Activity caching significantly improves performance.
Related
As the question states, can a shared method of an object be multithreaded? I don't quite having threading down in my skillset, otherwise I would test myself. On the other hand, I am involved in designing class that could be part of a multithreaded application in VB.Net.
If you mean "is it safe for a shared method to be called from multiple threads at once" - the answer is "it depends". A method itself isn't multi-threaded or single-threaded; threads and methods are very separate things.
If your shared method is called from multiple threads, then unless there's any synchronization to say otherwise, it will be executed concurrently on those threads. That can definitely cause a problem if your method uses shared state without appropriate safeguards. However, if the method either takes care when accessing shared resources (e.g. using locks) or it doesn't access any state which is shared between threads, that's fine.
Yes, it can. Any method can become a thread.
Yes, shared methods can be executed simultaneously by multiple threads. In fact, they often are. You do not have as much control over which threads are executing shared methods as compared to instance methods. Consider an ASP.NET application for example. Different page requests may come in on different threads. If you call a shared method in your web application then there is a high probability that it is getting executed by multiple threads.
This is an incredibly important point when designing an API. All self respecting API authors go to extremes to make sure all shared/static methods are thread-safe. Afterall, it would be ridiculously onerous to make a caller of your API synchronize access to every single shared/static method you provide. Take a look at the documentation Microsoft provides for almost all classes in the BCL.
Any public static (Shared in Visual Basic) members of this type are
thread safe. Any instance members are not guaranteed to be thread
safe.
I have yet to run across a static method provided by Microsoft that was not thread-safe.1 And that is good because it makes life easier for you and I.
1If you know of one let me know.
What is the best place to start a new thread? Should I create it in the Application Delegate, or can I start it from any other class for example a singleton?
Thanks for your help
if you're joining the thread, then you will typically want to create the thread local (or accessible to) the creation site, or in the same object's implementation. you'll usually join or use a task based interface when you want execution of the current thread to block until the threads/tasks complete.
if detaching (likely if you alloc an NSThread or use a detach... call), then it may be created wherever it makes the most sense in your program's flow.
That means you should favor 'local' as opposed to centralized in both cases.
If you use a task based interface (e.g. NSOperation), then you may need to centralize some things so many clients may reach an operation queue (as an example).
extracting detail from the comments: if you create a detached thread to interact with a server, then it is likely a good idea to create the thread in your implementation which interacts with the server, or the client code that interacts with those implementations. The app delegate is not a good choice when the cause/effect does not need to be centralized.
I'm still fairly new to Core Data and am trying to understand why it requires the passing around of a NSManagedObjectContext. As I understand it, passing the context is needed so that multiple threads don't affect the same context, but I was also under the impression that this pattern is sometimes considered an antipattern, as noted here.
Could Core Data theoretically be implemented in a thread safe way that would avoid using this pattern? How do other ORMs (such as Ruby's ActiveRecord for example) avoid this pattern? For example, couldn't CoreData implement a per-NSManagedObject saving method such as in this extension. This light framework doesn't handle multithreading, but couldn't NSManagedObjects use some kind of internal GCD queue(s) to support it, with an internal context they don't expose?
Sorry if I'm missing anything major.
The NSManagedObjectContext is the in-memory container of your applications object graph, just as the persistent store (XML, SQLite, etc.) usually represents the on disk container of your object graph.
There are some advantages to this approach:
Faulting can be applied to a set of objects, or in the case of CoreData the entire object graph
It's a convenient abstraction for forcing the application to batch it's I/O.
It provides a single point of contact for efficiently performing operations over the entire object graph (NSFetchRequests, etc.)
Undo can be applied to the object graph, not just individual objects.
It's also important to remember that CoreData is not an ORM framework, it's an object persistence framework. The primary responsibility of CoreData is to make accessing data stored in a persistent format on disk more efficient. However it doesn't attempt to emulate the functionality of relational databases.
To your point about concurrency, new concurrency models have been introduced in the upcoming release of Mac OSX. You can read more about that at developer.apple.com.
In the abstract though, the concurrency model chosen for a managed object context has more to do with the specifics of an individual application than the context pattern itself. Instances of NSManagedObjectContext should generally never be shared between threads.
In the same way that each thread requires it's own instance of NSAutoReleasePool, each thread should also have it's own MOC. That way, when the thread is done executing, it can commit it's changes to the store on disk and then release the context, freeing up all the memory consumed by objects processed on the thread.
This is a much more efficient paradigm than allowing a single context to continuously consume system resources during the lifecycle of a given application. Of course, this can be done by invoking -reset on the context as well, which will cause all of the NSManagedObject's in use by the context to be turned back in to faults.
You need one NSManagedObjectContext per thread. So you would have one to fill your UI on the main thread and for longer operations you would have another for each background thread. If you want results to be merged in from those other threads then there is a notification you can subscribe to that provides something to quickly merge what was changed into your main MOC.
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
Not during instantiation, but once instantiation of singleton object is done, what will happen if two or more threads are trying to access the same singleton object? Especially in the case where the singleton object takes lot of time to process the request (say 1 min)... In this case, if for ex., 5 threads try to access the same singleton object, what will the result be?
Additional question: normally when should we go for the singleton pattern and when should we avoid it?
Unless synchronization (locking) is being performed within the Singleton, the answer is this: it's a free-for-all.
Though the Singleton ensures that only one instance of an object is used when requested, the pattern itself doesn't inherently provide any form of thread safety. This is left up to the implementer.
In the specific case you cited (with a long running method), it would be critical to synchronize access to any method that uses class or object-level variables. Failure to do so would, in all likelihood, lead to race conditions.
Good luck!
The general rule of thumb i use for Singletons is that it should not affect the running code, and have no side-effects. Essentially for me, in my projects this translates into some kind of logging functionality, or static value lookup (ie. loading some common data from a database once and storing it for reference so it doesn't have to be read in everytime its needed).
A singleton is no different than any other object other than there is only one instance. What happens when you try to access it will largely depend on what the accessing threads are attempting (ie read vs write) and what kind of data your singleton is holding.
The answer to your question as it is, is "it really depends". What kind of singleton? i.e. what does it do, and how does it do it? And in what language?
The reality is that the singleton patter)n only dictates and enforces that you can only have one instance of a certain object. In of itself it does not say anything about multiple threads accessing that object.
So, if coded right (with thread synchronization implemented correctly) there is no reason why it shouldn't behave correctly - even if the requests to the object take a really long time to process!
Then you need thread safe implementation of singleton pattern.
Find this article useful for the same which describes most of the multi-threading scenario of singleton pattern.
HTH!