Pass sequence of steps (methods) to window (wpf)

0

Greetings ... I currently have a screen similar to the one below:

This screen uses BackgroundWorker to execute a sequence of steps and inform the user through the messages in the textblock a step by step of the tasks that are currently executing.

After the last step is finished, the log and close buttons are displayed and the ProgressBar (below the buttons) is stopped, thus informing the end of the processing.

I would like to reuse this screen for other operations, whose number of steps, each operation will have yours, so I do not know how to exemplify, but would like to turn to the screen a multi-step operation to be performed, another time would pass another operation with several other steps ... I want to reuse the log saving features and inform the user step by step.

I thought of something according to the classes below, but I do not know where to start:

public class Operacao1
{
    public void Inicia()
    {
        // Gostaria de atualizar a tela aqui!
        Passo1();
        // Aguarda a finalização do passo 1
        Passo2();
        // Aguarda a finalização do passo 2
        Passo3();
        // Gostaria de atualizar a tela aqui!
    }

    private void Passo1()
    {
        // Gostaria de atualizar a tela aqui!
        // implemento a funcionalidade...
        // Atualizo novamente a tela aqui!
    }

    private void Passo2()
    {
        // Gostaria de atualizar a tela aqui!
        // implemento a funcionalidade...
        // Atualizo novamente a tela aqui!
    }

    private void Passo3()
    {
        // Gostaria de atualizar a tela aqui!
        // implemento a funcionalidade...
        // Atualizo novamente a tela aqui!
    }
}

public class Operacao2
{
    public void Inicia()
    {
        // Gostaria de atualizar a tela aqui!
        Passo1();
        // Aguarda a finalização do passo 1
        Passo2();
        // Gostaria de atualizar a tela aqui!
    }

    private void Passo1()
    {
        // Gostaria de atualizar a tela aqui!
        // implemento a funcionalidade...
        // Atualizo novamente a tela aqui!
    }

    private void Passo2()
    {
        // Gostaria de atualizar a tela aqui!
        // implemento a funcionalidade...
        // Atualizo novamente a tela aqui!
    }
}

I would like to know if the BackgroundWorker would work, or if it would have to use a task, etc ... thanks for any help!

    
asked by anonymous 04.01.2017 / 19:42

1 answer

1

Next, Paul, what I understand is that you want a reusable canvas, I'll try to give you a light to give you continuity.

First, let me take your question below:

  

I would like to know if the BackgroundWorker would work, or if it would have to use a task, etc ... thanks for any help!

As Stephen Cleary explains in his Blog: link

  

BackgroundWorker is a type that should not be used in new code. Everything it can do, Task.Run can do better; and Task.Run can do a lot of things that BackgroundWorker can not!

Reading the article becomes clearer that the BackgroundWorker can, and should, be replaced by the Task. Remembering that the article is from 2013, it has been mentioned for 4 years.

On your issue, I made the following resolution:

I created a UserControl containing:

UserControl1.xaml

<Grid>
    <Label Content="OPERANDO" HorizontalAlignment="Center" FontSize="20"/>
    <ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto" Margin="40">
        <StackPanel x:Name="spResultado" Background="White">

        </StackPanel>
    </ScrollViewer>
</Grid>

The UserControl code

UserControl1.cs

 public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();
    }

    public async Task<bool> ExecutaAcao(Func<bool> Acao)
    {
        Task<bool> task = new Task<bool>(Acao);
        task.Start();
        await task;
        return task.Result;
    }

    public void InformaAcao(string value)
    {
        TextBlock txt = new TextBlock { Text = value };
        spResultado.Children.Add(txt);
    }

    public void ExibeResultado(string value)
    {
        TextBlock txt = new TextBlock { Text = value, Foreground = Brushes.Green };
        spResultado.Children.Add(txt);
    }

}

Our UserControl is ready to receive the information (remembering that this is just an example).

The idea is to put that UserControl where you need it and pass the information for it to process.

In the Interface your Window add it:

Window.xaml

<local:UserControl1 x:Name="UserControl1"/>

In the code of your Window it looks like this:

Window.cs

 //CRIA UM FUNC QUE RETORNARÁ TRUE OU FALSO PARA 
        Func<bool> baixaArquivos = new Func<bool>(() =>
        {
            // SEU PROCEDIMENTO AQUI
            // REMOVER ESSE THREAD.SLEEP, COLOQUEI ELE APENAS PARA SEGURAR O PROCESSO POR 5s
            System.Threading.Thread.Sleep(5000);
            // CASO SEU PROCEDIMENTO TEVE SUCESSO, RETORNE TRUE
            return true;
        });

        Func<bool> removeArquivos = new Func<bool>(() =>
        {
            System.Threading.Thread.Sleep(5000);
            return true;
        });
        Func<bool> instalaSistema = new Func<bool>(() =>
        {
            System.Threading.Thread.Sleep(5000);
            return true;
        });

        //INFORMA O USUARIO SOBRE QUAL PROCESSO ESTÁ SENDO EXECUTADO
        UserControl1.InformaAcao("Inicia processo de download do arquivo");
        //EXECUTA DE MANEIRA ASSINCRÓNICA A FUNC CRIADA ACIMA E RETORNA O STATUS
        if (await UserControl1.ExecutaAcao(baixaArquivos) == true) { UserControl1.ExibeResultado("Sucesso no download"); } else { MessageBox.Show("Erro na operação"); return; }


        UserControl1.InformaAcao("Remove antigos arquivos");
        if (await UserControl1.ExecutaAcao(removeArquivos) == true) { UserControl1.ExibeResultado("Sucesso na remoção dos arquivos"); } else { MessageBox.Show("Erro na operação"); return; }
        UserControl1.InformaAcao("Instalando novo sistema");
        if (await UserControl1.ExecutaAcao(instalaSistema) == true) { UserControl1.ExibeResultado("Sucesso ao instalar sistema"); } else { MessageBox.Show("Erro na operação"); return; }

This was just an example, there are other ways to do this. You can do with or without UserControl , it is your criterion. You can also pass Action or something else in place of Func.

Any questions just ask. Good Luck

    
17.01.2017 / 15:16