C# async & await, WPF application

Hi Experts,

I have a function that's setting the DataContext of a UserControl the following way:

m_MyBusinessObject = CreateMyBusinessObject();
base.DataContext = new MyViewModel( m_MyBusinessObject );

Open in new window


There are async & await calls within the CreateMyBusinessObject, so when I get to the DataContext assignment, there's nothing in the data fields of m_MyBusinessObject yet that the MyViewModel will build from, so the UserControl is created empty.

How do I wait for m_MyBusinessObject to be "filled in" properly by the await functions before passing it to the new MyViewModel without freezing up the UI?  The CreateMyBusinessObject call can take a very long time.

Thanks,
Mike
LVL 1
threadyAsked:
Who is Participating?
 
Michael FowlerConnect With a Mentor Solutions ConsultantCommented:
To stop the GUI from freezing during the operation use a backgroundworker
https://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

With the CreateMyBusinessObject call why not place some logic in the class which sets a variable once the operation is complete. You could use something like

m_MyBusinessObject = CreateMyBusinessObject();
while (m_MyBusinessObject.created != True)
{
    System.Threading.Thread.Sleep(500);
}

Open in new window

0
 
threadyAuthor Commented:
Of course!  Thank you  :)
0
 
threadyAuthor Commented:
Actually, I thought I understood, but I guess I don't.

If I create a background worker, how does that help me?  I've got the same problem.  I need to wait for that background worker to complete before setting my DataContext.  If I add the code above to a worker thread, sure my UI won't freeze up while it's creating the business object.  But when the thread has created the business object and then polls and waits for completion, once it completes, the worker thread then tries to set the DataContext and bam- exception because I'm on the wrong thread.
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

 
Michael FowlerSolutions ConsultantCommented:
If I understand correctly the core issue here is the length of time to create the BusinessObject class. Based on this I am suggesting you use backgroundworker to create and return this BusinessObject class and then continue processing as normal. To do this use the BackgroundWorker argument DoWorkEventArgs with its public property object Result. When your worker has generated its result  set e.Result and return.

eg

private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
    var mbo = CreateMyBusinessObject();
    while (m_MyBusinessObject.created != True)
    {
        System.Threading.Thread.Sleep(500);
    }
    e.Result = mbo ;
}

private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    m_MyBusinessObject  = e.Result;
}

Open in new window

0
 
threadyAuthor Commented:
I guess my real issue is, I have to add to my view model item by item (it's a treeview), instead of all in one shot like I'm doing after the whole tree gets created in the model.
0
 
Michael FowlerSolutions ConsultantCommented:
The suggestion above is just to replace the line

m_MyBusinessObject = CreateMyBusinessObject();

so that the m_MyBusinessObject  object creation is fully completed before creating a new ViewModel and so ensuring that this is not created empty.
0
 
threadyAuthor Commented:
Thank you again for your help!  Much appreciated.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.