Are the instance methods on Microsoft.Azure.Devices.Client.DeviceClient thread-safe? For example, is it safe to have a single instance of DeviceClient, and execute its methods concurrently from multiple threads?
Our current code base makes multiple concurrent calls to UploadToBlobAsync(), UpdateReportedPropertiesAsync(), and SendEventAsync(), all on the same instance. The documentation does not mention thread-safety at all, but I would like to confirm if the methods are thread-safe or not before reworking our current code base to manually prevent concurrent access to the instance methods.
Yes, DeviceClient is thread-safe, according to https://github.com/Azure/azure-iot-sdk-csharp/issues/1613. So you can safely call any instance methods in parallel using just one instance of DeviceClient.
Related
I am calling a large method via multiple threads and it has been quite difficult to prevent deadlock and race conditions using synclock around global field incrementing. The method calls other methods, and I am wondering if the threads would race in those other methods that are chained as well(?).
My thoughts are that if I instead instantiate a class, start the thread in the constructor, and then instantiate as objects and their methods all method calls in the first method, race conditions should be avoided.
An instantiated class owns its methods as well, so I believe methods and sub methods in an instantiated class should never race between each other. I therefore believe I could instantiate the class numerous times instead of even using threads -- and let GC catch up (may be inefficient?).
Perhaps this would work better instead of SyncLock:
Interlocked.Increment(myGlobalVariable)
Edit: I don't believe your theories about putting the methods in classes will help to prevent a data race. It should not matter where the methods are defined, if they attempt to modify the same data from different threads without an effective synchronization technique (e.g, a mutex), then a data race is a definite possibility.
Should properties be atomic in NSURLConnectionDataDelegate (NSURLConnectionDelegate) when there are more concurrent connections and properties are accessed by methods being called when connection reaches particular state?
There is no access from other threads to those properties invoked by me.
NSURLConnection's concurrency is run-loop-based, so as long as all the connections for which your object is a delegate are started from the same run loop, you shouldn't need to worry about concurrency in your delegate. If you start multiple connections scheduled on different run loops, then yes, you would need to protect the private state of your delegate objects. Atomic properties are rarely sufficient for this.
In short, you either don't need to worry about this, or atomic properties are unlikely to help. One easy option would be to have all your delegate methods dispatch_async their work to a private serial GCD queue.
While recently working with Objective-C and various libraries written in it, I've noticed two really popular singleton patterns. One version fetches the singleton instance and calls its instance methods and other version only exposes class methods and never gives you an instance to work with. All have the purpose of abstracting access to a single resource (StoreKit, CoreData, Parse API etc.). For example, here's the former approach used in MKStoreKit:
// initialize singleton during app boot
[MKStoreManager sharedManager]
// sometime later in the app
[[MKStoreManager sharedManager] buyFeature:kFeatureAId
onComplete:^(NSString* purchasedFeature)
{
NSLog(#"Purchased: %#", purchasedFeature);
}
onCancelled:^
{
NSLog(#"User Cancelled Transaction");
}];
or alternatively NSUserDefaults, UIApplication etc.. The other approach can be seen in MagicalRecord or here with Parse API:
// configure API credentials sometime during app boot
[Parse setApplicationId:#"123456"
clientKey:#"123456"];
// sometime later
PFObject *testObject = [PFObject objectWithClassName:#"TestObject"];
[testObject setObject:#"bar" forKey:#"foo"];
[testObject save];
What are some pros and cons of the two approaches and is one of them fundamentally better than the other?
Not having to retrieve the shared instance saves some screen estate (the performance difference is likely irrelevant), but am I screwing myself in some other way, for example, testability-wise?
Thanks!
There are two different ways to implement the approach based on class methods:
Make a singleton instance using a class hidden from everybody, and hide its methods behind wrapper class methods with identical signatures, or
Make class methods that do all the work
The implications of the first implementation are that everything you can do with a singleton, you can do with the hidden singleton:
using a subclass becomes a possibility
switching the instance in the middle of the run is easy
the state lives in instance variables
initialization follows the familiar pattern
If you go for an implementation that does not use a singleton, you would be relying on static variables to keep your current state. That is a legitimate choice, but the initialization pattern becomes different (perhaps even using a dispatch_once), you cannot switch the implementation in the middle without relying on some ugly if conditions, and using a subclass becomes a lot more tricky.
Testing the first implementation is somewhat easier than testing the second one, because you can provide a separate implementation of the singleton for testing, perhaps through the back door; with a static-based implementation, this route cannot be taken.
To summarize, I would use a singleton-based solution, with the singleton optionally hidden behind a "facade" that provides access to singleton's methods. I would not use an implementation where all state must be placed in static variables.
One advantage of the singleton approach is that it becomes trivial to allow other instances if you need to. If you take the class method approach, that's all you get without a lot of refactoring.
I have a singleton class which is being used throughout the app. I am working on another class that needs to send data to this singleton class, but can send data in bunch which will freeze the main thread.
Should I create another instance of this singleton class or should I should I create a data import utility as a separate class?
Singletons, as the name implies, are meant to have only a single instance floating around. Data freezing the main thread should be dispatched, another instance of a class won't help that.
Create another instance all you want, but don't call it singleton anymore.
Actually you should send this data in another thread and maybe use an NSLock while the data is being sent so you don't have any access errors.
Use:
[self performSelectorOnBackGround:#selector(sendDataToSingleton:) withObject:#"data to send"];
Don't create another instance of the singleton class or the rest of your application won't have access to it since it's a singleton.
Hope it helps.
By definition you should only have 1 instance of a singleton. If it's a properly constructed singleton it should not be possible to have more than 1!
If you are running into issues where your main thread is unresponsive, break the data you need to load into smaller chucks. This way, in between loading different chunks of data, the main thread can process any events it needs to and other objects can access the data in the singleton.
You could also implement a lazy data loading mechanism, where when an object wants information from the singleton, the singleton checks if your new class is waiting to give it new information and then loads it.
Can I share a single ACAccount instance between threads? Specifically I would like to create multiple TWRequest objects that are used by different NSOperationQueue instances. Those TWRequest objects will share a single ACAccount instance. Is that safe?
Thanks.
I'm going to say, "no." Firstly, ACAccount does not appear on Apple's "Thread Safe" list. Secondly, I see no explicit mention of thread safety in the reference for either of those classes. Thirdly, I see that TWRequest appears to be built upon NSURLConnection which is designed for use on a run loop (typically the main thread). I see nothing at all to indicate that these classes are safe for concurrent use from multiple threads. At best, you should take a thread-confinement approach (i.e. each thread fetches/creates its own copies of these objects and should not pass them between threads.)
Since TWRequest is designed for cooperative/runloop-based operation, I see no reason that you would need to do this stuff on a background thread either, FWIW.
So yeah. I'd say, "no."