I have some NSManagedObjects with a one-to-many parent-child relationship where the "children" property is an NSOrderedSet.
When I create a new child, I do so in a child NSManagedObjectContext. I insert the child at the index 0 of the children set.
Before I save the child context I observe that the parent's children look like:
Parent
Kid1
Kid2
Kid3
Kid4(new)
But when I proceed to save the parent context I check the "updatedObjects" property and see that the parent's children are ordered incorrectly!
Parent
Kid1
Kid2
Kid3
Kid4(new)
NOTE:
This only happens with newly created children. If the children already exist when I create the child context I am able to change their order on the child context and their positions in the ordered set are saved appropriately in the parent context.
I've tried messing with the merge policies of the parent and child contexts. Right now they are configured to the default error-policy and no errors are being thrown on save.
My main issue here was was related to cross-thread Core Data usage.
I expected the symptoms of cross-thread misuse to be more obvious, but this is how they manifested for me. Making sure I was accessing managed object contexts correctly from all threads fixed my problems.
Related
It has a situation that the control is instantiating(it's window handle is null) and it's parent control was instantiated.So the system will find it's parent thread id and compared with the control invoked thread id to make sure if it needs to invokeRequire.
But,why the system has to find it's parent thread id rather than find the Form thread id.I mean finding the Form thread id seems like more quickly and simpler?
Background:
I am using C#, but I think this question applies to Java and Scala as well. I have one master actor that passes along all "Job Messages". These jobs can be executed at the same time, as long as they don't share don't share a "concurrency id". To take care of this, I was spawning one child actor for each "concurrency id". I then used setReceiveTimeout to clean up the children when they've been idle.
What I can't figure out is how I can do this without a race condition. Here are a couple of ways that don't work:
1) Remove the child from the Dictionary, and tell the child to terminate. This does not work because messages might have been added to the child's queue between the time the timeout was fired, and before the parent started processing the message, resulting in messages being lost.
2) Remove the child from the Dictionary, and send a PoisonPill. This does not work because the child might continue to process new work. If more work reaches the parent, the parent would create a new child, and the means two thing with the same concurrency id are running at the same time.
3) Remove the child from the dictionary, and "ask" the child with a message. If the message returns
Is there any way the parent can ask the child if there are any messages in the child's queue? (This would not be a race condition, because all messages to the child come from the parent)
Can the parent check if the child's queue is empty, and the child isn't processing anything?
Should I add a new message and "ask" the child if it's done? (This would be safe because I know the parent is the only one who sends messages, but there's a moderate chance this might block if the child is processing a message, or if the there's no threads available in the dispatcher's pool.
My question is similar to this question, but I'm adding the additional constraint of the "concurrency id", and not worried about "zombie actors" who are currently shutting down, as long as the zombies have no work and won't get more work:
Get or create child Akka actor and ensure liveness
Akka makes sure that actor mailboxes are private. The mailbox of one actor is no business of another actor. A parent checking if the child's mailbox is empty would be wrong.
Why do you think ask would block?
One option: do not kill the children. If you have a fixed set of concurrency IDs you use over and over again and again, just keep all the actors alive. Actors do not consume too much resources.
Another option:
When the parent wants to kill the child:
send a PoisonPill to the child and remove him from the Dictionary.
When the parent receives a "job message" with concurrencyID:
if (Dictionary.contains(concurrencyID) {
send message to child
} else {
if (parent has child with name concurrencyID) {
delay message - for example with scheduler // child is terminating
} else {
create a child with name concurrencyID
send message to child
}
}
I am having an issue in Wicket, which I think may be more related to Java.
How to I handle a class that is serializable and has a running thread when it is serialized? I am losing state of the Thread when the class is serialized and then deserialized. My Thread reference is global, but when the class comes back the reference is null and the thread is still running. The List I am using and delcared inside the main class, and passed to the runnable class remains alive but no longer gets filled by the thread. The thread is still filling a List object but I am not seeing any updates in the main class...
I am using List batchLines = Collections.synchronizedList(new CopyOnWriteArrayList());
If your thread is running outside the page, so it should be better to reference it in your Application that is a singleton, e.g. use a map to put a unique id such as page hashCode. Just be careful about memory leaks.
I have a form that is responsible for creating and setting up an instance of an object, and then telling the object to go do its work. The process is a long one, so there's an area on the form where status messages appears to let the user know something is happening. Messages are set with a setMessage(string msg) function. To allow the form to remain responsive to events, I create a new thread for the object to run in, and pass it the setMessage function as a delegate to allow the object to set status messages on the form. This part is working properly. The main form is responsive and messages posted to its setMessage function appear as expected.
Because the process is a long one, and is made up of many steps, I want to allow the user to terminate the process before it's finished. To do this I created a volatile bool called _stopRequested and a function called shouldStop() that returns its value. This is also given to the object as a delegate. The object can tell if it should terminate by checking shouldStop() periodically, and if it's true, shut down gracefully.
Lastly, Windows controls are not thread safe, so the compiler will complain if a thread other than the one that created the control tries to manipulate it. Therefore, the setMessage function is wrapped in an if statement that tests for this and invokes the function using the parent thread if it's being called from the worker thread (see http://msdn.microsoft.com/en-us/library/ms171728(v=vs.80).aspx for a description).
The problem arises when the user requests a shutdown. The main form sets _stopRequested to true and then waits for the child thread to finish before closing the application. It does this by executing _child.Join(). Now the parent thread (the one running the form) is in a Join state and can't do anything. The child thread (running the long process) detects the stop flag and attempts to shut down, but before it does, it posts a status message by calling it's setMessage delegate. That delegate points back to the main form, which figures out that the thread setting the message (child) is different than the thread that created the control (parent) and invokes the function in the parent thread. The parent thread is, of course, in a Join state and won't set the text on the text box until the child thread terminates. The child thread won't terminate because it's waiting for the delegate it called to return. Instant deadlock.
I've found examples of signaling a thread to terminate, and I've found examples of child threads sending messages to the parent thread, but I can't find any examples of both things happening at the same time. Can someone give me some pointers on how to avoid this deadlock? Specifically, I'd like the form to wait until the child thread terminates before closing the application but remain able to do work while it waits.
Thanks in advance for the advice.
1-(lazy) Dispatch the method from a new Thread so it doesn't lock
2-(re-think) The main UI thread should be able to control the child thread, so forget the _stopRequested and shouldStop() and implement a childThread.Abort() , abort does not kill the thread, but sends a ThreadAbortException
which can be handled or even canceled
catch(ThreadAbortException e)
{
ReleaseResources();
}
Make the ReleaseResources safe by making various checks such as:
resource != null
or
resource.IsClosed()
The ReleaseResources should be called normally without abort and also by abort.
3-(if possible)stop the child, via main thread call ReleaseResources()
You may have to implement a mix of these.
I have to perform a fetch via NSFetchedResultsController on a background thread.
My current solution is structured like that:
dispatch_queue_t fetchQueue = dispatch_queue_create("backgroundfetching", NULL);
dispatch_async(fetchQueue,^{
// 1. Create NSManagedObjectContext
// 2. Create NSFetchRequest
// 3. Create NSFetchedResultsController
// 4. PerformFetch
dispatch_async(dispatch_get_main_queue(),^{
[[self table] reloadData];
});
});
dispatch_release(fetchQueue);
My first tests ran well but is that the appropriate way?
Since the fetched results controller is intended to control the data that defines a tableview, it belongs on the foreground thread/operation that the UI runs on. It's rather pointless to put it on a background thread as you would lose all the advantages of using it in the first place.
I would also be concerned about the effects of sending the FRC delegate messages across asynchronous threads. I'm not sure how reliable that would be.
Having said all that, the sketch of your implementation looks fine as far as it goes.
I believe there is something fundamentally wrong with this approach, as you're sharing managed objects across threads (you're fetching objects on one thread and referencing them on your main thread). In practice it will work, but will sometimes lead to crashes. Because Apple makes it clear that the only ways to share managed objects across threads is using the objectWithID: method or the MOCDidSave notifications.
From the Core Data Programming Guide:
You fetch in one managed object context on a background thread, and
pass the object IDs of the fetched objects to another thread. In the
second thread (typically the application's main thread, so that you
can then display the results), you use the second context to fault in
objects with those object IDs (you use objectWithID: to instantiate
the object).