I want the SaveChanges of the ObjectContext (Win apps) to save changes asynchronously, will show a marquee (or controllable?) progress bar (this I can easily implement) for the user while he is able to continue working.
I basically want to override the SaveChanges of the ObjectContext.
Has anyone thought about this before?
Entity Framework itself currently does not support asynchronous operations. Mainly because it's built on top of ADO.NET where this isn't supported either. ADO.NET isn't even thread safe by default.
You can use the delegate approach above or wrap it into Task. But that will not use any async calls even if the provider supports it. Also during this "background" operation you should not do anything with the ObjectContext (querying, adding objects, ...) as may result in corrupted state.
Related to multithreading you can read this post. It's older, but ideas are still valid.
Edit 2013-04-17:
EF6 (the next version, currently in alpha stage in time of writing) will support asynchronous operations, namely your requested SaveChangesAsync. It also extended ADO.NET model, so if the provider itself supports asynchronous execution it will be really asynchronous (else back to former behavior as there's nothing better (wise) to do).
Warning: The answer below is old and may not apply to the most recent versions of the framework in question.
I believe you need to use Asynchronous Delegates. It basically works like that:
You create a delegate from the method you want to call asynchronously;
You call BeginInvoke on the delegate, starting a call;
You do whatever else you need to do (e.g. animate a marquee);
You can either wait for the async call to finish, or check whether is has completed and keep animating the marquee if it isn't;
Related
I am calling a monitoring task via thread using the following code which is called from the viewDidLoad() in a ViewController:
let myDaemon = Thread(target: self.myMonitor, selector:#selector(self.myMonitor), object: nil)
myDaemon.start()
I have been unable to find a way to find and cancel that thread without closing the app. Is there maybe an alternate way to launch the thread so I can cancel it if needed?
I thought about creating an observer so I could cancel it from another VC but since the Daemon is initialized in the viewDidLoad, I can't access it outside of that block.
I'm using Swift 5. Any suggestions are appreciated.
Thanks,
First, you should almost never use Thread in Swift. Directly accessing threads has been discouraged in Cocoa since longer than Swift has been a language. You should generally be using, in order of preference for the kinds of problems threads are usually used for, async/await (possibly plus an AsyncChannel), OperationQueues, or DispatchQueues. That said, it's a fine question, and there are still very rare cases where a Thread would be appropriate, or at least useful.
To cancel a thread, you will either need to keep track of it (the returned value) so you can call .cancel(), or you need to have a way to communicate with the thread (a Pipe for example) so that you can send a custom "stop" message. That means storing that returned value (or the communication mechanism) somewhere outside the VC.
A ViewController should not own a global object like a Thread. ViewControllers come and go. You should move your thread management (if you're going to do thread management, which you generally shouldn't) into a model object that the VCs share.
Note that canceling a thread does not cause a thread to stop running. The only thing it does is set the isCancelled flag. If is still up to your thread to periodically check itself for cancellation and stop. (You may already know this, but it's a very common confusion, so I want to make sure anyone reading this later is aware.)
There is no list of all existing threads for you to search (and that would be pretty obnoxious since the frameworks generate quite a lot of threads you would need to crawl through). If you want to keep track of a thread, you need to store it somewhere.
The other day, in a code review, I saw some questions about the safety of setting a property from a worker thread. A coworker made the comment, "This property is bound to the UI, and data binding is thread-safe."
I've been using XF for a while, but always assumed this wasn't true: that if I wanted to update ViewModel properties bound to the UI I'd have to make those changes on the UI thread. I just spent a few minutes poking around the documentation, and I don't see an obvious answer other than that directly manipulating BindableProperties has thread affinity. It also matters to me if that's a blocking UI thread execution or not.
I could make a project to test it out myself, but these kind of issues always seem to be intermittent so I'd like to know I'm just missing the right documentation.
(It's relevant to investigating a crash we're seeing that happen within mainly Xamarin call stacks. We raise an event from a worker thread, a VM handles that event and updates some properties. If that's being scheduled for the UI thread, there could be some interleaving issues we didn't prepare for and I'm that much closer to addressing the crash. If it's not being scheduled for the UI thread... I'm surprised it's worked this long.)
I've been using XF for a while, but always assumed this wasn't true: that if I wanted to update ViewModel properties bound to the UI I'd have to make those changes on the UI thread.
You're right. 100% right. You can use Device.InvokeOnMainThread() for this.
To be complete, there is one case where it doesn't matter: PropertyChanged
https://github.com/xamarin/Xamarin.Forms/blob/b645064/Xamarin.Forms.Core/BindingExpression.cs#L542
In that case, the Binding is applied on the main (UI) thread.
Assumptions
We interact with the UI exclusively via binding. So only setters and getters are playing.
Getters
The code referred to in github by #Stephane, only means, that your bound getter(s) will be called in the UI thread. No more no less.
Btw, I would not rely on the source code (I mean: implementation), instead the specification what matters. Implementation can change anytime, and if the specification does not requires this, then unit tests will not check this, so there will be a big surprise...
Setters
However it is still not clear, if can you call your setter(s) in a background thread. Regardless the answer is yes or no, it implies further tasks to solve.
a) If you can call setters in any thread: This means, that your viewmodel internal data is exposed to race conditions, because will be called from the UI thread, and you will access them in a background thread. Conclusion: You must guard the data with the usual concurrency patterns, or use thread safe classes, plus: your getter and setter must be atomic.
b) If it turns out you can not call setters in any thread: Then you must use Device.InvokeOnMainThread(). But this is only the half of the story. In methods of your background thread, you are modifying say a List instance. This will be accessed in the UI thread by the getter, and you are modifying it in a background thread concurrently when you say populate it. Theoretically it is possible the user interacts with the UI during the population period, what let the binding evaluated, getter is called.
Conclusions:
If there are multiple threads accessing to the very same data, you must always lock you data.
Regardless what the current source code implies the safest way to marshall the getter and setter to the UI thread. This will not cause significant overhead: If the executions is already in the UI thread, marshall will do nothing.
Note: Even you marshall both you getters and setter to the UI thread, you will access the data in background threads so guard against race conditions or using thread safe classes are essential.
We are building a React-Native iOS app that needs to access our realms natively as well as via RN.
We have writing working correctly from our UI and can load the data in our background Swift service, but after the write, The changes_available method in js_realm.cpp is firing which contains assert(0) which is causing the app to crash/hang in debug. What do we need to be doing to prevent that method from firing?
Update: A release was just made (0.11.1) which should prevent this crash from occurring. Note that notifications across bindings have not yet been tested and may not work.
This method gets called when changes are made externally to a Realm from another process or thread. In your case it sounds like writes made from the swift apis are causing this method to get called. The ReactNative binding was written with the assumption that everything would be done from a single thread without considering the use of other language bindings being used simultaneously.
As is the only thing you can to do prevent this is to not make a write in Swift while a Realm is open in JS. One way to do this would be to call Realm.close after every use, although this may perform poorly.
In the near term we can also do a point release to remove the assert(0) - this will prevent the crash/hang, but notifications for changes made in Swift wont work without additional changes. Can't give an estimate of when we can get cross language notifications working properly.
Im using a large amount of very small web services in my app and I have been down a couple of roads that does not scale or work as desired.
The Design approach Im thinking about:
The task for the viewController is to ask for a set of data from a general webServicesClass, this task is started in a new NSThread -> this will instantiate an object which solely retrieves the xml and returns it to the webServicesClass -> the webServicesClass now instantiates an object which solely can Parse some XML coming from this particular web service. The Parser then returns a nice Entity object to the webServiceClass. The WebserviceClass now needs to inform the viewController about this data.
The viewController implements a webServiceClassDelegate and some delegate methods to see if the web service request went as planned. e.g. -(void)aWebserviceFailed and -(void)aWebserviceSuccess.
0.5 Since the WebserviceClass is running is a different NSThread, will it be a problem calling delegate methods on the main NSThread in the parent object?
1.0 I think this design is sound as it completely incapsulates the retrieval, parsing and returning of the Entity in different classes. But, I will have to write delegation methods and implement delegation protocols on each step of the way, for each different webservice. i.e. starting from the bottom, the WebserviceClass must implement delegation methods for both the object that retrieves the XML (start, fail, success), then for the object that parses the XML(start, fail, success) and the WebserviceClass must be able to delegate each of these responses to the viewController that again must implement delegation methods from the WebserviceClass(start, fail, success).
Is there a much simpler way to do this?
I have some design pattern experience, but not from languages that uses delegation so consistently as Objective C. In AS3 or Java I would have events that could bubble up through the objects and inform whoever was listening about changes. In all the Objective example code I have read I have only seen NSNotifications (which would be the equivalent of the AS3 or Java 'Event') used 0.1% of the times.
The Design I described will give me something that scales perfectly for many web services and gives me complete control over where a potential error/exception happens, but it seems to be a lot of code to obtain this loose coupling.
1.1 Or should I fully embrace the delegation approach and get to work:)
Thanks for any pointers or help given. Im not asking for source code or the likes, more a "this is considered best practice in Objective C in the every day situation you just described" :)
I'd recommend taking a look at ASIHttpRequest(obtainable here) and NSOperation + NSOperationQueue (docs here). I don't think you should run a long-lived thread to talk to your web service all the time, unless you absolutely need a constant connection.
Basically ASIHttpRequest and NSOperation both encapsulate all of the networking and threading stuff. Operations make multi-threading on the iPhone really nice. Essentially you create an operation (through a factory or whatnot for ease of use), pop it in a queue and do something with the result.
As for what you do with the result (this applies to your original scenario too and 0.5 and 1.1) what typically happens is your operation/thread will then call a didSucceedAtGettingWhatever or didFailWithError:(NSError*) method. Delegation is pretty much the defacto way of making requests on the phone. If there are multiple delegates, then you can just use subject-observer, like you would in Java.
As for 1.0, ultimately no. What we typically do is we have an OperationDelegate and OperationTypes. Based upon which OperationType succeeded or completed, we have different logic. It's not the greatest and there are a ton of different ways of doing this, but you will have to have separate logic for separate events regardless of what you do. Whether or not that's in one method or many methods is up to you.
Not even sure if the title is correct, however, what I'm trying to do is use the standard NSURLConnection class to handle responses from calling my webservice. I am using the POST method to update a database and the GET method to retrieve rows from the database. The problem I have is that these 2 actions may occur simultaneously so that the methods to handle the request may step on each other. In other words in my "connection didReceiveData" method I have 2 paths through the code depending on whether I'm handling a response from a GET or POST request.
I keep track on which request in being processed by an instance variable called requestType. The problem is that since the requests are being executed simultaneously the instance variable is being changed from GET to POST before the GET completes (or vice-versa). My question is how do I maintain 2 separate requests in this scenario? Do I synchronize the requests? Is there a way for threads to work here? Do I create 2 separate objects for each of the requests and have the logic in "didRecieveData" query for which object is being processed? Any help would be much appreciated!!
Dealt with a similar issue in one of our apps. The solution involved creating a class that represents a webservice call, responsible for calling its own url, loading its own data, etc. The call class had a delegate that would handle parsing the responses (in our case, a web service controller). Wound up getting rather complicated, but prevented the issue of NSURLConnections stepping on each other.
Seems like you've created a messy problem by having a class that tries to do too many things. I would suggest taking one of the following three approaches:
1) Write two classes, one for updates and one for retrievals. Each class creates it's own private NSURLConnection object and acts as the delegate for the async notifications received from the NSURLConnection. The classes could possible share some utility parsing code or extend a base object that has that parsing code in it. But the key being that the code calling these classes would instantiate one of them, make the call, and then release it. This will keep your code cleaner and will insure that the event notifications don't get intermingled.
2) Create a single class that, depending on initialization, does either a post or a get with it's own private instance of NSURLConnection. When a call needs to be made, instantiate the class, get the results, and then release the class.
3) Write your connection handling classes so they use the synchronous NSURLConnection method and call that call that class in a background thread.
Either way, clean code and clear object orientation will prevent messy scenarios like the one you're describing.
Create separate objects that handle the calls. If you want to issue multiple requests at once I would strongly recommend looking at NSOperationQueue, and making these objects subclasses of NSOperation... much nicer way to deal with multiple background requests.
A good example is here:
http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/
The idea there is that you use the non-asyncronous web calls, in operations that are run on separate threads. You can still use asynch calls in NSOperation as well, but doing so is a little trickier and for simple calls you probably do not need to.