Click here to Skip to main content
15,887,135 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi
I have a search through database. Search works in separate thread. When entity is found I have to show it and some of related data into WPF UI.

I use EntityFramework. Main idea of search process is:
C#
foreach (var item in _currentEntitySet)
{     
    Items.Add(item);
    OnItemFound(item);
}


Where _currentEntitySet is an ObjectQuery

But I have met some problems. When OnItemFound is fired, I try to use BeginInvoke() to display found item and some related object in UI.

C#
private void OnCatalogueItemFound(CatalogueItem item)
{
    Application.Current.Dispatcher.BeginInvoke(new Action<object>((param) =>
    {
        var model = new CatalogueResultItemViewModel(param as CatalogueItem);
        TitlesResultViewModel.Add(model);
    }), System.Windows.Threading.DispatcherPriority.Background, item);
}


The problem is that navigation properties of item are NULL

When I use Invoke() instead of BeginInvoke() then things works fine. I have to use exactly BeginInvoke() because of some other reasons.

Does anyone knows how can I use BeginInvoke() in my situation? Thanks :)
Posted
Comments
Mark Salsbery 22-Nov-11 15:07pm    
Is your code thread safe? After the foreach loop ends, there can still be items queued for dispatching on the UI thread...does anything happen at the end of the foreach loop that would make the queued data items be invalid or inaccessible?
Sergey Alexandrovich Kryukov 22-Nov-11 17:26pm    
This is a valid concern. I would suspect the problem is just different order of certain calls which is of course can be different in case of Invoke vs BeginInvoke.
--SA
Sergey Alexandrovich Kryukov 22-Nov-11 17:38pm    
Some more ideas in my solution.
--SA
Renat Khabibulin 22-Nov-11 20:08pm    
In case when I use BeginInvoke() then foreach doesn't ends because I get exception after first result returned because it's navigation properties are NULLs and I am trying to use them. I think that I will have to solve problem of thread safety after I understand why navigation properties are NULL in case of BeginInvoke()
Sergey Alexandrovich Kryukov 22-Nov-11 17:41pm    
What's the question? "Does anyone know?" Be careful: I was tempted to answer just "I know". :-)
Why BeginInvoke and not Invoke? You cannot ask a question like that without explanation of such things, otherwise how can we really motivate the solution, in some cases?
--SA

1 solution

Please see the comment by Mark and my comment to the question.

You just need to understand the difference between Invoke and BeginInvoke operations and infer the conclusion by yourself because only you have the whole code. A change from one method to another may change the order of calls.

By the way, you can observe the order of execution it by logging some information form different place of your code using the class System.Diagnostics.EventLog http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.aspx[^]. If you use the Debugger, you can introduce time delay which can change the picture (race condition, see http://en.wikipedia.org/wiki/Race_condition[^]).

The delegate used in the call to Invoke or BeginInvoke from any thread other then the thread of you UI is never called on a calling thread. Instead, it is dispatched by adding it to an event queue of the UI thread. The UI retrieve the delegate and parameters required to make a call and calls it on the UI thread. If you use BeginInvoke, the method returns right after the delegate and call parameters are queued, but Invoke is blocking the called until the delegate is actually called on the UI thread. This different behaviors can cause different order of some operations.

You can analyze your code and/or use EventLog to figure out what happens.

See also my past solutions:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

—SA
 
Share this answer
 
v2
Comments
Renat Khabibulin 22-Nov-11 20:10pm    
I know difference between Invoke and BeginInvoke :) I ll try to use EventLog to understand what happens...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900