A.Pissicat
A.Pissicat

Reputation: 3293

Display UserControl when working

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 :

enter image description here

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

Answers (2)

Rudra
Rudra

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

mm8
mm8

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

Related Questions