Reputation: 936
my problem is that when the user clicks on a button, SpeicherUser() is being called. It creates a xml file by using XMLSerialization asynchronously. So when the user clicks very fast and all the time on the button, the task is being called over and over again and if it's not completed (creating new xml file), an AggregateException pops up.
This is the code:
public class UserList
{
private static List<User> _personen = new List<User>();
public List<User> Personen
{
get { return _personen; }
set { _personen = value; }
}
public static StorageFile file { get; set; }
private const string filename = "Personen.xml";
public UserList()
{
md.Title = "Fehler beim Speichern";
Personen = new List<User>()
{
new User(){ID = 1,
Name = "TestUser1"},
new User(){ID = 2,
Name = "TestUser2"}
};
}
public async Task SpeicherUser()
{
await Save<UserList>();
}
static async public Task Save<T>()
{
if (await DoesFileExistAsync(filename))
{
//AggregatException pops up here: UserList.SaveAsync<T>().Wait()
await Windows.System.Threading.ThreadPool.RunAsync((sender) => UserList.SaveAsync<T>().Wait(), Windows.System.Threading.WorkItemPriority.Normal);
}
else
{
file = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
}
}
static async Task<bool> DoesFileExistAsync(string fileName)
{
try
{
await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
return true;
}
catch
{
return false;
}
}
static async private Task SaveAsync<T>()
{
StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
IRandomAccessStream sessionRandomAccess = await sessionFile.OpenAsync(FileAccessMode.ReadWrite);
IOutputStream sessionOutputStream = sessionRandomAccess.GetOutputStreamAt(0);
var serializer = new XmlSerializer(typeof(List<User>), new Type[] { typeof(T) });
//Using XmlSerializer
serializer.Serialize(sessionOutputStream.AsStreamForWrite(), _personen);
sessionRandomAccess.Dispose();
await sessionOutputStream.FlushAsync();
sessionOutputStream.Dispose();
}
}
The UserList is shown in a ListView. I have at the moment 1 button, so when the user clicks on the button, a new 'User' will be added into the ListView and it creates right after it the XML file. To solve my problem, I could do a wordkaround by using 2 buttons: - One for adding a User into the ListView - The other one will only be enabled, when the user creates a new User. So the XML file will be saved and the button will be disabled. But this is not a real solution... Like I said, it's only a workaround and not actually fixing the problem.
Question: How can I handle the AggregateException at static async public Task Save<T>()
which says 'One or more errors occurred.' -> Access denied (Exception from HRESULT: 0x80070005 (EACCESSDENIED)
Upvotes: 0
Views: 400
Reputation: 456987
Asynchronous programming does force you to design your UI a bit differently. In this case, your UI has an additional state which is creating user.
One common approach to handling these short-lived states is to disable the button while the operation is in progress, e.g.:
async void AddButton_Click(..)
{
addButton.IsEnabled = false;
await Save();
AddToListView();
addButton.IsEnabled = true;
}
Alternatively, you could just catch the exception and ignore it (since it likely means there is already an Add
in progress).
Upvotes: 2