Persist layouts in background via new Thread/Task

2 posts, 0 answers
  1. Johannes
    Johannes avatar
    66 posts
    Member since:
    Dec 2012

    Posted 27 Mar 2015 Link to this post

    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:

    01.// --- Part of CustomRadGradView.cs (inherits from RadGridView) ---
    02.
    03.// Save this RadGridViews layout in background
    04.Task.Run(() =>
    05.    {
    06.        using (var manager = new CustomPersistenceManager())
    07.        {
    08.            // this is current RadGridView
    09.            manager.SaveLayout(this, file);
    10.        }
    11.    }
    12.}

    01.// --- Part of CustomPersistenceManager.cs (inherits from PersistenceManager) ---
    02. 
    03.// Save a layout of any Telerik control
    04.public bool SaveLayout(Control control, string file = null)
    05.{
    06.    // Current thread has no access to control -> Invoke required
    07.    if (control.Dispatcher.CheckAccess() == false)
    08.    {
    09.        bool result = false;
    10.        Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => result = DoSaveLayout(control, file)));
    11.        return result;
    12.    }
    13. 
    14.    // Current thread has access to control
    15.    return DoSaveLayout(control, file);
    16.}

    01.// --- Part of CustomPersistenceManager.cs (inherits from PersistenceManager) ---
    02. 
    03.// save layout
    04.private bool DoSaveLayout(Control control, string file = null)
    05.{
    06.    // this lines work without any errors so method is invoked correctly; thread has access to control!
    07.    string name = control.Name; // returns name of control
    08.    control.Name = "New name"; // just for testing
    09.     
    10.    // Next line always throws an InvalidOperationException
    11.    using (var stream = Save(control)) // call save method of Teleriks PersistenceManager class
    12.    {
    13.        stream.Seek(0, SeekOrigin.Begin);
    14. 
    15.        using (var reader = new StreamReader(stream))
    16.        {
    17.            string text = reader.ReadToEnd();
    18.            File.WriteAllText(path, text);
    19.        }
    20.    }
    21.}


    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. Kiril Vandov
    Admin
    Kiril Vandov avatar
    324 posts

    Posted 31 Mar 2015 Link to this post

    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.

     
  3. UI for WPF is Visual Studio 2017 Ready
Back to Top