Reputation: 696
I'am trying to make a simple application that loads data and performs an action on it. So my idea was to do this async.
I have 3 data sources and i would like to load them async. So for example Data1.xml, Data2.xml and Data3.xml all files are quite big to load so it takes some time (that's why i would like async).
So for example i made a window with 3 Textboxes that all bind to a specific property (Text1, Text2, Text3) and a button. When i click on the button i would like to execute 3 functions async (MakeText1,MakeText2, ...). I made MakeText3 the fastes one so normally i would have to see Text3 first. It doesn't work, what am i doing wrong?
private string _text1;
public string Text1
{
get { return _text1; }
set { _text1 = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Text1"));
}
}
private string _text2;
public string Text2
{
get { return _text2; }
set
{
_text2 = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Text2"));
}
}
private string _text3;
public string Text3
{
get { return _text3; }
set
{
_text3 = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Text3"));
}
}
public AsyncWin()
{
InitializeComponent();
this.DataContext = this;
}
private async Task MakeText1()
{
for (double i = 0; i < 7000000; i++)
{
_text1 = i.ToString();
}
Text1 = _text1;
}
private async Task MakeText2()
{
for (double i = 0; i < 3000; i++)
{
_text2 = i.ToString();
}
Text2 = _text2;
}
private async Task MakeText3()
{
for (double i = 0; i < 10; i++)
{
_text3 = i.ToString();
}
Text3 = _text3;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
_text1 = "";
_text2 = "";
_text3 = "";
Test();
Console.WriteLine();
}
public async void Test()
{
MakeText1();
MakeText2();
MakeText3();
}
public event PropertyChangedEventHandler PropertyChanged;
Xaml:
<Grid>
<TextBox x:Name="txt1" HorizontalAlignment="Left" Height="181" Margin="10,19,0,0" TextWrapping="Wrap" Text="{Binding Text1}" VerticalAlignment="Top" Width="110"/>
<TextBox x:Name="txt2" HorizontalAlignment="Left" Height="181" Margin="137,19,0,0" TextWrapping="Wrap" Text="{Binding Text2}" VerticalAlignment="Top" Width="110"/>
<TextBox x:Name="txt3" HorizontalAlignment="Left" Height="181" Margin="276,19,0,0" TextWrapping="Wrap" Text="{Binding Text3}" VerticalAlignment="Top" Width="110"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="10,219,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
</Grid>
Upvotes: 1
Views: 165
Reputation: 726489
I would like that the UI show Text3 first than Text2
This does not happen in your code, because the artificial delay loops inside the setters for Text1
..Text3
runs synchronously, without letting other tasks having a go. If you replace these loops with Task.Delay(...)
, you will get the desired effect:
private async Task MakeText1() {
await Task.Delay(3000);
Text1 = "3 seconds";
}
private async Task MakeText2() {
await Task.Delay(2000);
Text2 = "2 seconds";
}
private async Task MakeText3() {
await Task.Delay(1000);
Text3 = "1 second";
}
Upvotes: 3