Reputation: 3293
I'm in C# WPF.
My application contains a button used to load a file. It can take some seconds, so I created a circular progress bar like this :
But when I click on the load button, the progress bar is not displayed. It seems to be a problem with threading but I don't know how it properly works.
There is my code : MainWindow.xaml:
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid>
<local:CircularProgressBar Panel.ZIndex="1"
Visibility="Collapsed"
x:Name="progressBar"/>
<Button Content="Load file"
Command="{Binding LoadCommand}"/>
</Grid>
MainWindow.xaml.cs:
public MainWindow()
{
InitializeComponent();
(DataContext as MainViewModel).OnWork += MainWindow_OnWork;
}
private void MainWindow_OnWork(object sender, bool isStart)
{
if (isStart)
progressBar.Visibility = Visibility.Visible;
else
progressBar.Visibility = Visibility.Collapsed;
}
MainViewModel.cs:
protected RelayCommand loadCommand;
private String file;
public delegate void WorkEventHandler(object sender, bool isStart);
public event WorkEventHandler OnWork;
public ICommand LoadCommand
{
get
{
if (loadCommand == null)
{
loadCommand = new RelayCommand(Load, CanLoad);
}
return loadCommand;
}
}
private void Load()
{
OpenFileDialog opnfldlg = new OpenFileDialog();
opnfldlg.Multiselect = false;
if (opnfldlg.ShowDialog() == true)
{
if (OnWork != null)
OnWork(this, true);
// This is the part who takes a time
Task<ReadResult> readTask = Task.Factory.StartNew(() => ReadImage(opnfldlg.FileName));
Task.WaitAll(readTask);
ReadResult result= readTask.Result;
if (OnWork != null)
OnWork(this, false);
}
}
Upvotes: 0
Views: 73
Reputation: 144
if you want to wait for the task then you can use below code.
Task.WaitAll(readTask).ConfigureAwait(continueOnCapturedContext: false);
Above will force task to not wait for the result on UI thread.
Upvotes: 1
Reputation: 169380
Task.WaitAll blocks the UI thread and a single thread cannot both wait and update the UI simultaneously. Try to await the Task asynchronously using async/await:
private async void Load()
{
OpenFileDialog opnfldlg = new OpenFileDialog();
opnfldlg.Multiselect = false;
if (opnfldlg.ShowDialog() == true)
{
if (OnWork != null)
OnWork(this, true);
// This is the part who takes a time
ReadResult result = await Task.Factory.StartNew(() => ReadImage(opnfldlg.FileName));
if (OnWork != null)
OnWork(this, false);
}
}
Upvotes: 1