I have a simple metro app contains a button, a label and a drop down list. The drop down list contains a list of files that I can read from. When I click on the button, the selected file’s content gets read into the label. Files are in the Documents folder (i.e WinRT’s KnownFolders.DocumentsLibrary). Each file represents a StorageFile in WinRT API.
File reading method is an asynchronous method (uses async/await). In order to prove the asynchronous behaviour, I made the file reading method as a long running process. Therefore, while executing this long running method, I should be able to freely click on the drop down list and select a different file. This is because the UI thread should not get blocked while reading the file. However this is not currently happening. It still seems to be blocking UI thread, and drop down list get frozen while the long running method occurs.
I must be doing something odd here. Can you please tell me why the UI is non responsive?
My code sample is below.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace FileAccess
{
public sealed partial class MainPage : Page
{
private readonly StorageFolder storageFolder;
public MainPage()
{
this.InitializeComponent();
storageFolder = KnownFolders.DocumentsLibrary;
AddFiles();
}
private async void AddFiles() //Add files to the drop down list
{
var filesList = await storageFolder.GetFilesAsync();
IEnumerable<FileItem> fileItems
= filesList.Select(x => new FileItem(x.Name, x.Name));
cboSelectFile.ItemsSource = fileItems;
cboSelectFile.SelectedIndex = 0;
}
private async void BtnReadFile_Click(object sender, RoutedEventArgs e)
{
IStorageFile storageFile = await storageFolder.GetFileAsync((string)cboSelectFile.SelectedValue);
if (storageFile != null)
{
LblReadFile.Text = await ReadFileAsync(storageFile); //long running method**************
}
}
private async Task<string> ReadFileAsync(IStorageFile storageFile) //long running method**************
{
var fileContent = await FileIO.ReadTextAsync(storageFile);
for (Int64 i = 0; i < 10000000000; i++)
{
}
return fileContent;
}
}
}
If you execute code like this on a UI thread:
Then
// some more codewill also execute on the UI thread. Which is exactly your problem. After the file is read, you execute the long loop on the UI thread, which is why the UI freezes.If you want to simulate some long-running operation, you can do it several ways:
Execute the loop on a background thread using
Task.Run(), and asynchronously wait for it to finish:Don’t waste CPU time and use
Task.Delay()to delay executing of the code: