Eu tenho um pouco de código que preciso executar em um thread diferente da GUI, pois atualmente faz com que o formulário congele enquanto o código é executado (10 segundos ou mais).
Suponha que eu nunca criei um novo segmento antes; o que é um exemplo simples / básico de como fazer isso em C # e usando o .NET Framework 2.0 ou posterior?
c#
.net
multithreading
p.campbell
fonte
fonte
Respostas:
Um bom lugar para começar a ler é Joe Albahari .
Se você deseja criar seu próprio encadeamento, é o mais simples possível:
fonte
IsBackground
como true. Provavelmente não faz o que você pensa que faz. O que ele faz é configurar se o encadeamento será eliminado quando todos os encadeamentos em primeiro plano morrerem ou se o encadeamento manterá o aplicativo ativo. Se você não deseja que seu encadeamento seja finalizado no meio da execução, não configureIsBackground
como true.BackgroundWorker
parece ser a melhor escolha para você.Aqui está o meu exemplo mínimo. Depois de clicar no botão, o trabalhador em segundo plano começará a trabalhar no encadeamento em segundo plano e também relatará seu progresso simultaneamente. Também será relatado após a conclusão do trabalho.
Nota:
ProgressChanged
ou nosRunWorkerCompleted
manipuladores. No entanto, atualizar a GUI deDoWork
causaráInvalidOperationException
.fonte
O ThreadPool.QueueUserWorkItem é bastante ideal para algo simples. A única ressalva é acessar um controle do outro segmento.
fonte
Rápido e sujo, mas funcionará:
Usando no topo:
código simples:
Acabei de jogar isso em um novo aplicativo de console para um exemplo
fonte
Aqui está outra opção:
fonte
Tente usar a classe BackgroundWorker . Você fornece delegados para o que executar e para ser notificado quando o trabalho terminar. Há um exemplo na página do MSDN ao qual vinculei.
fonte
Se você deseja obter um valor:
fonte
Coloque esse código em uma função (o código que não pode ser executado no mesmo encadeamento que a GUI) e, para acionar a execução desse código, coloque o seguinte.
Thread myThread= new Thread(nameOfFunction);
workerThread.Start();
Chamar a função de início no objeto de encadeamento causará a execução da sua chamada de função em um novo encadeamento.
fonte
nameOfFunction
em segundo plano, e não no thread da GUI atual. AIsBackground
propriedade determina se o thread manterá o aplicativo ativo ou não: msdn.microsoft.com/en-us/library/…Aqui, como usar threads com um progressBar, é apenas para sublinhar como os threads funcionam, no formulário há três botões progressBar e 4:
fonte
Charles, seu código (acima) não está correto. Você não precisa girar a espera para concluir. EndInvoke bloqueará até que o WaitHandle seja sinalizado.
Se você deseja bloquear até a conclusão, basta
ou alternativamente
Mas qual é o sentido de emitir chamadas anyc se você bloquear? Você também pode usar uma chamada síncrona. Uma aposta melhor seria não bloquear e passar um lambda para limpeza:
Uma coisa a ter em mente é que você deve ligar para o EndInvoke. Muitas pessoas esquecem isso e acabam vazando o WaitHandle, pois a maioria das implementações assíncronas libera o handhandle no EndInvoke.
fonte
Se você for usar o objeto Thread bruto, precisará configurar o IsBackground como true no mínimo e também definir o modelo Threading Apartment (provavelmente STA).
Eu recomendaria a classe BackgroundWorker se você precisar de interação da interface do usuário.
fonte
outra opção, que usa delegados e o Pool de threads ...
assumindo 'GetEnergyUsage' é um método que usa um DateTime e outro DateTime como argumentos de entrada e retorna um Int ...
fonte
int usageCnt = nrgDel.Invoke(lastRunTime, procDT, null, null);
? Parece que suspende thread atual com o sono de qualquer maneira ... Eu pensei que ele vai ajudar nada com GUI congelamento se você chamá-lo em fio de GUIExistem várias maneiras de executar threads separados no .Net, cada um com comportamentos diferentes. Você precisa continuar executando o encadeamento após o encerramento da GUI? Você precisa passar informações entre o thread e a GUI? O thread precisa atualizar a GUI? O encadeamento deve executar uma tarefa e encerrar ou deve continuar em execução? As respostas a essas perguntas lhe dirão qual método usar.
Há um bom artigo sobre método assíncrono no site do Code Project que descreve os vários métodos e fornece código de exemplo.
Observe que este artigo foi escrito antes da introdução do padrão async / waitit e da Task Parallel Library no .NET.
fonte
Como usar um segmento de plano de fundo para procurar arquivos
Você precisa ter muito cuidado com o acesso de outros threads a coisas específicas da GUI (é comum em muitos kits de ferramentas da GUI). Se você deseja atualizar algo na GUI a partir do processamento do thread, verifique esta resposta que eu acho útil para o WinForms. Para o WPF, veja isso (mostra como tocar o componente no método UpdateProgress () para funcionar com outros threads, mas, na verdade, eu não gosto que isso não esteja ocorrendo
CheckAccess()
antes doBeginInvoke
Dispathcer, consulte e procure o CheckAccess nele)Estava procurando um livro específico do .NET sobre encadeamento e encontrou este (disponível para download gratuito). Consulte http://www.albahari.com/threading/ para obter mais detalhes.
Acredito que você encontrará o que precisa para iniciar a execução como novo encadeamento nas primeiras 20 páginas e tem muito mais (não tenho certeza sobre trechos específicos da GUI, quero dizer estritamente específicos ao encadeamento). Ficaria feliz em ouvir o que a comunidade pensa sobre este trabalho, porque eu estou lendo este. Por enquanto, parecia bem legal para mim (por mostrar métodos e tipos específicos do .NET para threading). Também abrange o .NET 2.0 (e não o antigo 1.1) o que eu realmente aprecio.
fonte
Eu recomendo consultar a Power Threading Library de Jeff Richter e, especificamente, o IAsyncEnumerator. Dê uma olhada no vídeo de Charlie Calvert blog de onde Richter o para uma boa visão geral.
Não se deixe levar pelo nome, porque isso facilita a codificação das tarefas de programação assíncrona.
fonte