I am developing a windows 8.1 app for the first time and running it (debugging mode) within visual studio 2013 as I develop.
I have a main .xaml page with a frame containing my menu (listview) and another frame containing the page that user has selected at that moment.
When my page2 loads it writes to a file in storage and then reads the value, this is my proof of concept for basic reading and writing of data.
The first time page2 loads everything works ok, but the second time the file is still locked and it throws the following error in WriteTimeStamp():
Error:
An exception of type 'System.IO.FileLoadException' occurred in mscorlib.dll but was not handled in user code
Additional information: The process cannot access the file because it is being used by another process. (Exception from HRESULT: 0x80070020)
Code Snippets
//Main.Xaml - showing the layout
<Grid>
<Frame x:Name="BasicLayout" Grid.Column="0">
<ListView>
<!-- Menu items... -->
</ListView>
</Frame>
<Frame x:Name="SpecificLayout" Grid.Column="1">
</Frame>
</Grid>
// Main Page navigation logic
void itemListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListViewItem itemClicked = (ListViewItem)e.AddedItems[0];
if(itemClicked != null && itemClicked.Tag != null && !string.IsNullOrEmpty(itemClicked.Tag.ToString()))
{
switch (itemClicked.Tag.ToString())
{
case "Page1":
SpecificLayout.Navigate(typeof(Page1));
break;
case "Page2":
SpecificLayout.Navigate(typeof(Page2));
break;
case "Page3":
SpecificLayout.Navigate(typeof(Page3));
break;
}
}
}
// Page 2 initialisation
public Page2()
{
this.InitializeComponent();
WriteTimestamp();
ReadTimestamp();
}
// Page 2 read/write file logic
async void WriteTimestamp()
{
myTextbox.Text = "saving timestamp";
Windows.Globalization.DateTimeFormatting.DateTimeFormatter formatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("longtime");
StorageFile sampleFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("dataFile.txt", CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(sampleFile, formatter.Format(DateTime.Now)); // THIS LINE THROWS THE ERROR
}
async void ReadTimestamp()
{
try
{
StorageFile sampleFile = await ApplicationData.Current.LocalFolder.GetFileAsync("dataFile.txt");
String timestamp = await FileIO.ReadTextAsync(sampleFile);
// Data is contained in timestamp
myTextbox.Text = timestamp;
}
catch (Exception)
{
// Timestamp not found
}
}
You're calling ReadTimeStamp before WriteTimeStamp finishes writing. Async functions return when they reach an await while the awaited Task goes off and does its thing. When the awaited Task completes the function continues on the next statement.
Define WriteTimeStamp as async Task instead of async void so it can be awaited. Since it's void you just need to change WriteTimestamp's return value and (by convention) it's name. You'll also need to move the calls outside of Page2's constructor since the constructor cannot be async.
async Task WriteTimestampAsync()
{
myTextbox.Text = "saving timestamp";
Windows.Globalization.DateTimeFormatting.DateTimeFormatter formatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("longtime");
StorageFile sampleFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("dataFile.txt", CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(sampleFile, formatter.Format(DateTime.Now)); // THIS LINE THROWS THE ERROR
}
...
async void DoTimeStampStuff()
{
await WriteTimestampAsync();
await ReadTimestampAsync();
}
User contributions licensed under CC BY-SA 3.0