I have read some stuff about async/await, but I can't, for the life of me, understand how it works.
My scenario is quite simple : I click on a button which display a file picker. Once a file is picked, I read it line by line to do some data management. The file loads quickly but the processing takes some time, so I'd like to have a progress bar or something - at least my UI should not be frozen.
I tried putting async or await there and there : nothing's working and I'd like to understand what I'm supposed to do, in a proper way.
private async void BtnLoadFile_Clicked(object sender, EventArgs e)
{
var result = await FilePicker.Default.PickAsync();
if (result != null)
{
// Read the stream - this is quick
Stream s = await result.OpenReadAsync();
// Treat the file - this need to run on another thread
DoLenghtyStuff(s);
}
}
private void DoLenghtyStuff(Stream s)
{
// Do some long stuff here, update the UI with a progress bar
}
I started some digging and stumbled on this post :How and when to use ‘async’ and ‘await’
So I did some changes :
private async void BtnLoadFile_Clicked(object sender, EventArgs e)
{
var result = await FilePicker.Default.PickAsync();
if (result != null)
{
// Read the stream - this is quick
Stream s = await result.OpenReadAsync();
// Treat the file - this need to run on another thread
await DoLenghtyStuff(s);
}
}
private async Task<int> DoLenghtyStuff(Stream s)
{
// Do some long stuff here
await Task.Delay(1); // 1 second delay
return 1;
}
... to no avail :it's still freezing and doing an await Task.Delay(1); does not seem to be the way to go.
Update : I used Task.Run() but have an error : "Only the original thread that created a view hierarchy can touch its views". It seems its when I try to update Label.Text. Funny enough, displaying updates in a ProgressBar element works ok though.
Here's my new code :
private async void BtnLoadFile_Clicked(object sender, EventArgs e)
{
var result = await FilePicker.Default.PickAsync();
if (result != null)
{
invalidLines = new List<string>();
chatList = new List<ChatLine>();
// Do Stuff with the file
Stream s = await result.OpenReadAsync();
// Treat the file
await Task.Run(() => { FileHandler(s); });
}
else
{
// Display the logs
frmLogs.IsVisible = true;
frmLogs.BackgroundColor = Color.FromArgb("b47d7d");
lblLogs.Text = $"aborted by the user";
}
}
private void FileHandler(Stream s)
{
int realLines = 0;
int keptLines = 0;
int totalLines = 0;
//using (StreamReader sr = new StreamReader(s, Encoding.GetEncoding("iso-8859-1")))
using StreamReader sr = new(s, Encoding.GetEncoding("UTF-8"));
// Read
while ((sr.ReadLine()) != null)
totalLines++;
// Reset position
s.Position = 0;
sr.DiscardBufferedData(); // reader now reading from position 0
string currentLine;
// Read first line to skip it
currentLine = sr.ReadLine();
realLines++;
while ((currentLine = sr.ReadLine()) != null)
{
realLines++;
// Progress bar
prgBarLines.Progress = ((double)realLines / totalLines);
lblProgress.Text = $"{Math.Round((double)realLines / totalLines * 100)}%"; // <= This crashes
// Long Data processing here : Regex checks, etc...
}
}