0

I am trying to serialize with sharpSerializer. But I get TargetInvocationException and InnerException as UnauthorizedAccessException: "Invalid cross-thread access".

Here my code for serializing:

public static async Task Save<T>(this T obj, string file)
{
    await Task.Run(() =>
    {
        IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
        IsolatedStorageFileStream stream = null;

        try
        {
            stream = storage.CreateFile(file);
            var serializer = new SharpSerializer();
            serializer.Serialize(obj, stream); // Exception occurs here
        }
        catch (Exception)
        {
        }
        finally
        {
            if (stream != null)
            {
                stream.Close();
                stream.Dispose();
            }
        }
    });
}

I'm serializing in App.xaml.cs

private void Application_Closing(object sender, ClosingEventArgs e)
{
    hs_layout.Save("layout.xml");
}

Type of hs_layout

public static List<Homescreen> hs_layout = new List<Homescreen>();

Homescreen class

public class Homescreen 
    {
        public List<UIElement>[ , ] Main { get; set; }
        public List<UIElement>[ ] Dock { get; set; }
        
        public Homescreen()
        {
            Main = new List<UIElement>[5, 4];
            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    Main[i, j] = new List<UIElement>();
                }
            }

             Dock = new List<UIElement>[5];                    
            for (int j = 0; j < 5; j++)
            {
                 Dock[j] = new List<UIElement>();
            }
        }
    }
Eliahu Aaron
  • 4,103
  • 5
  • 27
  • 37
Rishabh876
  • 3,010
  • 2
  • 20
  • 37

2 Answers2

0

The async task performs asynchronous tasks on thread pool threads, so it runs another thread instead of UI thread, but it access the UI elements, thus caused this exception.

Windows allows UI elements to be accessed only by the thread that created them. This means that a background thread in charge of some long-running task cannot update a text box when it is finished. Windows does this to ensure the integrity of UI components. A list box could look strange if its contents were updated by a background thread during painting.

I think this rule also apply to the Windows Phone development. Don't use task, just call the function and see how it goes.

Matt
  • 6,010
  • 25
  • 36
  • so should i serialize like this -> this.Dispatcher.BeginInvoke(delegate() { serializer.Serialize(obj, stream); }); – Rishabh876 Apr 11 '14 at 18:36
  • according to MSDN:http://msdn.microsoft.com/en-us/library/ms741870(v=vs.110).aspx, it should work – Matt Apr 11 '14 at 18:39
  • Check this example:http://stackoverflow.com/questions/15529006/updating-ui-thread-from-timercallback-function-windows-phone-8 – Matt Apr 11 '14 at 19:08
0

This worked for me

public static async Task Save<T>(this T obj, string file)
        {
            Deployment.Current.Dispatcher.BeginInvoke((Action)(() =>
                    {
                IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
                IsolatedStorageFileStream stream = null;

                try
                {
                    stream = storage.CreateFile(file);
                    var serializer = new SharpSerializer();

                    serializer.Serialize(obj, stream);


                    //serializer.Serialize(obj, stream);
                }
                catch (Exception)
                {
                }
                finally
                {
                    if (stream != null)
                    {
                        stream.Close();
                        stream.Dispose();
                    }
                }
            }));
        }

        public static async Task<T> Load<T>(string file)
        {

            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
            T obj = Activator.CreateInstance<T>();

            if (storage.FileExists(file))
            {
                IsolatedStorageFileStream stream = null;
                try
                {
                    stream = storage.OpenFile(file, FileMode.Open);
                    var serializer = new SharpSerializer();

                    obj = (T)serializer.Deserialize(stream);
                }
                catch
                {
                }
                finally
                {
                    if (stream != null)
                    {
                        stream.Close();
                        stream.Dispose();
                    }
                }
                return obj;
            }
            await obj.Save(file);
            return obj;
        }
    }
Rishabh876
  • 3,010
  • 2
  • 20
  • 37