App freezes on button click

rolfMrolfM ATMember ✭✭

So I am working on an UWP app that I'm creating in a portable class library (Xamarin). I need to save information that are typed in (e.g. in TextBoxes) by a user in an xml file.

Therefore I created a class in PCL where I get the info from those TextBoxes:

    namespace myProject
    {
        public class XMLData
        {
            [XmlRoot("MyRootElement")]
            public class MyRootElement
            {
                [XmlAttribute("MyAttribute1")] //name of the xml element
                public string MyAttribute1     //name of a textboxt e.g.
                {
                    get;
                    set;
                }
                [XmlAttribute("MyAttribute2")]
                public string MyAttribute2
                {
                    get;
                    set;
                }
                [XmlElement("MyElement1")]
                public string MyElement1
                {
                    get;
                    set;
                }
        }
    }

On each Page there is a "continue" button. When clicked, the data gets saved:

    async void Continue_Clicked(object sender, EventArgs e)
            {
                await Navigation.PushAsync(new Page2());
                XMLData.MyRootElement mre = new XMLData.MyRootElement
                {
                    MyAttribute1 = editor1.ToString(),
                    MyAttribute2 = editor2.ToString(),
                    MyElement1 = editor3.ToString()
                };
            }

At the last button click the file should be created and saved:

    private void CreateandSave_Clicked(object sender, EventArgs e)
            {
                var s = DependencyService.Get<IFileHelper>().MakeFileStream();//using dependencyService to get a stream (there is no system.io.stream in PCL)
                XMLData xmldat = new XMLData();
                using (StreamWriter sw = new StreamWriter(s, Encoding.UTF8))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(XMLData));
                    serializer.Serialize(sw, xmldat);
                }
            }

Here my code in the UWP class (for dependencyService I created a class called FileHelper to get a stream and create a saving location + file)

    namespace myProject.UWP
    {
        public class FileHelper: IFileHelper //IFileHelper is a simple interface I made with the Stream MakeFileStream(); method in it
        {
            public async Task<IRandomAccessStream> MakeFileStreamAsync()
            {
                StorageFolder sf = KnownFolders.DocumentsLibrary;

                var file = await sf.CreateFileAsync("data.xml", CreationCollisionOption.OpenIfExists);
                var stream = await file.OpenAsync(FileAccessMode.ReadWrite);
                return stream;
            }
            Stream IFileHelper.MakeFileStream()
            {
                var task = MakeFileStreamAsync();
                task.Wait();
                return task.Result.AsStreamForWrite();
            }
        }
    }

The problem is that whenever I reach the CreateandSave button and click on it, the app just freezes. No errors, nothing, everything looks fine. After I break up the debugging I can see that there is an xml file created in the folder I wanted but it's empty (0 bytes). What's wrong with the code? Anyone an idea?

Best Answer

  • rolfMrolfM AT ✭✭
    Accepted Answer

    Alright thanks to these nice people stackoverflow.com/questions/42578573/serialization-taking-way-too-long/42581444?noredirect=1#comment72296813_42581444 I've been able to solve my problem. Turns out it was an issue with the threadUI or something.

    here is the fixed code in UWP project:

    namespace Workforce_Utility.UWP
    {
        public class FileHelper: IFileHelper
        {
            public async Task<IRandomAccessStream> MakeFileStreamAsync()
            {
                StorageFolder sf = KnownFolders.DocumentsLibrary;
    
                var file = await sf.CreateFileAsync("data.xml", CreationCollisionOption.ReplaceExisting);
                var stream = await file.OpenAsync(FileAccessMode.ReadWrite);
                return stream;
            }
            async Task<Stream> IFileHelper.MakeFileStream()
            {
                var stream = await MakeFileStreamAsync();
                return stream.AsStream();
            }
        }
    }
    

    and the fixed click handler:

        private async void CreateandSave_Clicked(object sender, EventArgs e)
                {
                    var s = await DependencyService.Get<IFileHelper>().MakeFileStream();
                    XMLData xmldat = new XMLData();
                    using (StreamWriter sw = new StreamWriter(s, Encoding.UTF8))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(XMLDaten));
                        serializer.Serialize(sw, xmldat);
                    }
                }
    

    and small adjustments in the IFileHelper interface:

    namespace Workforce_Utility.classes
    {
    
        public interface IFileHelper
        {
            Task<Stream> MakeFileStream();
        }
    
    }
    

Answers

  • rolfMrolfM ATMember ✭✭
    Accepted Answer

    Alright thanks to these nice people stackoverflow.com/questions/42578573/serialization-taking-way-too-long/42581444?noredirect=1#comment72296813_42581444 I've been able to solve my problem. Turns out it was an issue with the threadUI or something.

    here is the fixed code in UWP project:

    namespace Workforce_Utility.UWP
    {
        public class FileHelper: IFileHelper
        {
            public async Task<IRandomAccessStream> MakeFileStreamAsync()
            {
                StorageFolder sf = KnownFolders.DocumentsLibrary;
    
                var file = await sf.CreateFileAsync("data.xml", CreationCollisionOption.ReplaceExisting);
                var stream = await file.OpenAsync(FileAccessMode.ReadWrite);
                return stream;
            }
            async Task<Stream> IFileHelper.MakeFileStream()
            {
                var stream = await MakeFileStreamAsync();
                return stream.AsStream();
            }
        }
    }
    

    and the fixed click handler:

        private async void CreateandSave_Clicked(object sender, EventArgs e)
                {
                    var s = await DependencyService.Get<IFileHelper>().MakeFileStream();
                    XMLData xmldat = new XMLData();
                    using (StreamWriter sw = new StreamWriter(s, Encoding.UTF8))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(XMLDaten));
                        serializer.Serialize(sw, xmldat);
                    }
                }
    

    and small adjustments in the IFileHelper interface:

    namespace Workforce_Utility.classes
    {
    
        public interface IFileHelper
        {
            Task<Stream> MakeFileStream();
        }
    
    }
    
  • rolfMrolfM ATMember ✭✭

    There is still a problem: The file is empty. Only the xml header showing up, not my actual elements. Any idea?

Sign In or Register to comment.