This is a migrated thread and some comments may be shown as answers.

Persist layouts in background via new Thread/Task

2 Answers 93 Views
PersistenceFramework
This is a migrated thread and some comments may be shown as answers.
Johannes
Top achievements
Rank 1
Johannes asked on 27 Mar 2015, 04:30 PM
I want the layouts of some of my RadControls to be persisted in background via a new Thread/Task. The corresponding method is invoked so I can access the control that should be persisted without any error. But I'm always getting an exception at the time I call PersistenceManager.Save(control). Here's my code:

// --- Part of CustomRadGradView.cs (inherits from RadGridView) ---
 
// Save this RadGridViews layout in background
Task.Run(() =>
    {
        using (var manager = new CustomPersistenceManager())
        {
            // this is current RadGridView
            manager.SaveLayout(this, file);
        }
    }
}


// --- Part of CustomPersistenceManager.cs (inherits from PersistenceManager) ---
 
// save layout of any Telerik control
public bool SaveLayout(Control control, string file = null)
{
    // Current thread has no access to control -> Invoke required
    if (control.Dispatcher.CheckAccess() == false)
    {
        bool result = false;
        Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => result = DoSaveLayout(control, file)));
        return result;
    }
 
    // Current thread has access to control
    return DoSaveLayout(control, file);
}
 
// save layout to stream
private bool DoSaveLayout(Control control, string file = null)
{
    // this lines work without any errors so method is invoked correctly; thread has access to control!
    string name = control.Name; // returns name of control
    control.Name = "New name"; // just for testing
 
    // Next line always throws an InvalidOperationException
    using (var stream = Save(control)) // call save method of Teleriks PersistenceManager class
    {
        stream.Seek(0, SeekOrigin.Begin);
 
        using (var reader = new StreamReader(stream))
        {
            string text = reader.ReadToEnd();
            File.WriteAllText(path, text);
        }
    }
}


Can you please provide help why PersistenceManager.Save method is always throwing an exception here? How to use PersistenceManager to save a layout in background/new Task?

2 Answers, 1 is accepted

Sort by
0
Accepted
Kiril Vandov
Telerik team
answered on 31 Mar 2015, 08:21 AM
Hello Johannes,

In order to save data to using the RadPersistenceFramework you just need to call simply its Save() method, you can find more information about in this article. However in your case you are getting InvalidOperation Exception "The calling thread cannot access this object because a different thread owns it" as you are creating the PersistanceManager in one thread and use try to use it from another. You can easily solve this issue if you move the Dispatcher logic directly after calling the Task:
Task.Run(()=>
{
    if (this.invisibleButton.Dispatcher.CheckAccess() == false)
    {
        Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
        {
            using (var provider = new CustomPersistenceManager())
            {
                provider.SaveLayout(this.invisibleButton, file);
            }
        }));
    }
});
and remove the logic from the SaveLayout.

I hope this information helps.

Kind regards,
Kiril Vandov
Telerik
 

See What's Next in App Development. Register for TelerikNEXT.

 
0
Johannes
Top achievements
Rank 1
answered on 01 Apr 2015, 10:23 AM
Okay I see my mistake. Thank you very much for your help - now it works fine.
Tags
PersistenceFramework
Asked by
Johannes
Top achievements
Rank 1
Answers by
Kiril Vandov
Telerik team
Johannes
Top achievements
Rank 1
Share this question
or