Pergunta

Você tem uma boa solução para manter um 'por favor, aguarde' winform 'pintado' enquanto um aplicativo está executando uma tarefa de longa execução?

Eu tentei usar o form.Refresh () em cada etapa, mas existem algumas consultas longas que ocorrem, o que significa que isso não é frequente o suficiente.

Basicamente, isso Então pergunta Mas, em C# no Excel através do Vsto (em vez de Python).

Foi útil?

Solução

Aqui está um bom exemplo com código em C#.

É para telas de respingos especificamente, no entanto, é um processo quase idêntico (talvez menos parte da opacidade chamativa) criar uma janela de espera.

A principal informação é que você precisará de um encadeamento separado. Isso pode complicar as coisas, no entanto, o artigo fornece uma boa cobertura/exemplo de como fazê -lo corretamente.

Outras dicas

Como Statichippo mencionou, eu usaria a classe BackgroundWorker. Seu objetivo é simplificar o multi-threading e permitir que um thread de trabalhador consumisse o processamento que consome tempo sem travar a GUI.

Aqui está uma citação de Msdn:

A classe BackgroundWorker permite executar uma operação em um encadeamento separado e dedicado. Operações demoradas, como downloads e transações de banco de dados, podem fazer com que a interface do usuário (UI) pareça que parou de responder enquanto estiver em execução. Quando você deseja uma interface do usuário responsiva e se depara com longos atrasos associados a essas operações, a classe BackgroundWorker fornece uma solução conveniente.

Aqui está um bom tutorial sobre como usar a classe BackgroundWorker nos formulários do Windows: Implementando multi-threading em winforms usando a classe BackgroundWorker

Existem maneiras mais complicadas de implementar multi-threading em c# para cenários complexos, mas para a maioria dos cenários simples, o trabalho de fundo funciona muito bem (pelo menos para mim).

Aqui estão alguns links que retirei do Google no C# Multi Threading:
MSDN Threading
Introdução ao multithreading em C#

Outra opção é usar um delegado assíncrono para mostrar o formulário em um encadeamento Threadpool.

Os threads no Threadpool são recomendados para threads de vida mais curtos que não duram toda a duração do aplicativo. Como isso é para exibir uma janela de vida curta, aguarde, o Threadpool é uma opção razoável.

O delegado de ação (.NET 2.0+) é usado junto com o método BegininVoke () para executar automaticamente o código delegado em um encadeamento Threadpool.

Algumas notas:

  • É importante usar o Control.BegininVoke para qualquer chamada GUI da Cross Thread, como fechar o formulário Aguarde em ClosePleasewait ().
  • Também o m_pleaseWaitForm.ShowDialog(); Na verdade, inicia um novo loop de mensagem no novo thread. É isso que mantém o formulário de espera por favor.
  • Como um encadeamento ThreadPool é usado, este thread é automaticamente um encadeamento em segundo plano e será encerrado se o aplicativo principal for fechado.
  • Além de correr em outro tópico, não há nada de especial no Form2. Você pode colocar quaisquer controles infantis, como caixas de imagem, etiquetas etc.
  • (MethodInvoker)delegate { ... } é apenas uma maneira .NET 2.0 de executar o código em um delegado embutido.

O exemplo abaixo pode ser adicionado a um projeto WinForms contendo o formulário1: o formulário principal e o formulário 2: o formulário de espera.

   private Form2 m_pleaseWaitForm = null;

    private void Form1_Shown(object sender, EventArgs e)
    {
        // This code could also be placed in eg. a button click event handler.

        Action<Rectangle> a = new Action<Rectangle>(ShowPleaseWait);

        a.BeginInvoke(this.Bounds, null, null);

        // Do your long running tasks

        ClosePleaseWait();
    }


    private void ShowPleaseWait(Rectangle  bounds)
    {
        // This method runs on the new thread.

        m_pleaseWaitForm = new Form2();

        m_pleaseWaitForm.TopMost = true;
        m_pleaseWaitForm.Location = new Point(bounds.Left + bounds.Width / 2 - m_pleaseWaitForm.Width / 2, bounds.Top + bounds.Height / 2 - m_pleaseWaitForm.Height / 2);

        m_pleaseWaitForm.ShowDialog();

    }

    private void ClosePleaseWait()
    {
        m_pleaseWaitForm.BeginInvoke((MethodInvoker)delegate { m_pleaseWaitForm.Close(); });
    }

Use um trabalho de fundo

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top