使用sharpSerializer进行序列化时的TargetInvocationException

时间:2014-04-11 16:57:12

标签: c# serialization windows-phone-8

我正在尝试使用sharpSerializer进行序列化。但我得到TargetInvocationException和InnerException为UnauthorizedAccessException:无效的跨线程访问。

这是我的序列化代码

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();
            }
        }
    });
}

我在App.xaml.cs中序列化

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

hs_layout的类型

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

主屏幕课

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>();
            }
        }
    }

2 个答案:

答案 0 :(得分:0)

异步任务在线程池线程上执行异步任务,因此它运行另一个线程而不是UI线程,但它访问UI元素,从而导致此异常。

Windows允许UI元素仅由创建它们的线程访问。这意味着负责某个长时间运行任务的后台线程在完成时无法更新文本框。 Windows这样做是为了确保UI组件的完整性。如果在绘制过程中后台线程更新了其内容,则列表框可能看起来很奇怪。

我认为此规则也适用于Windows Phone开发。不要使用任务,只需调用该函数并查看它是如何运行的。

答案 1 :(得分:0)

这对我有用

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;
        }
    }