Pergunta

Eu recentemente tentou usar backgroundworker em vez de tópicos "clássicos" e eu estou percebendo que ele está causando, pelo menos para mim, mais problemas do que soluções. Eu tenho um backgroundworker executando uma leitura síncrona (neste caso a partir de SerialPort) e ficar bloqueado cerca de 30 segundos em uma linha de código, em seguida, cancellationpending não é a solução. Estou vendo que, se o pedido for fechada neste momento (ou com o botão cruz e Application.Exit ()) o processo mantém zumbi sempre.

Eu preciso de uma maneira de forçar a abortar ou matar o fio backgroundworker.

Foi útil?

Solução

Eu não estou muito certo sobre o que você está tentando realizar, mas talvez o evento SerialPort.DataReceived é uma solução melhor?

Se você já está acostumado com o uso de threads, eu não vejo o ponto em usar BackgroundWorker. Ele foi projetado para pessoas que não entendem tópicos em primeiro lugar.

Além disso, eu não gosto da idéia de abortar um fio. Parece perigoso, e aplicações de vários segmentos não precisa mais correr riscos.

Outras dicas

I colocar um conjunto que (eu acho) faz o trabalho. Por favor, deixe-me saber se im Waaaay off. Aqui é um simples exaple de como ele funciona.

var backgroundWorker = new BackgroundWorker(){WorkerSupportsCancellation = true};

backgroundWorker.DoWork += (sender, args) =>
         {                 
                 var thisWorker = sender as BackgroundWorker;
                 var _child = new Thread(() =>
                                               {
                                                   //..Do Some Code

                                               });
                 _child .Start();
                 while (_child.IsAlive)
                 {
                     if (thisWorker.CancellationPending)
                     {
                         _child.Abort();
                         args.Cancel = true;
                     }
                     Thread.SpinWait(1);
                 }                 
         };

 backgroundWorker.RunWorkerAsync(parameter);
 //..Do Something...
backgroundWorker.CancelAsync();

Uma vez que o trabalho de fundo é parte do pool de threads, nós não queremos abortá-lo. Mas podemos executar um thread internamente que pode permitir que um abort para ocorrer em. O backgroundworker então basicamente é executado até que o segmento infantil está completo ou nós sinalizamos a ela para matar o processo. O segmento de trabalho de fundo pode então voltar para o pool de leitura. Normalmente eu vou envolvê-lo em uma classe auxiliar e passar através do método delegado que eu quero que o segmento de segundo plano para executar passado como o parâmetro e executar que no segmento infantil.

Por favor, alguém me avise se im batendo a cabeça contra uma parede, mas parece funcionar bem .. Mas isso é o problema com tópicos não é ele .. os resultados variados você pode começar quando você executá-lo em momentos diferentes.

O processo não deve se tornar um zumbi, uma vez que o fio BackgroundWorker é marcado como "fundo" e deve terminar quando a UI está fechada.

Eu não acho que os suportes BackgroundWorker morte de rosca. Cancelamento de uma operação deve ser feito no método que realiza o trabalho. No seu caso eu acho que um fio regular será a melhor opção.

Você pode tentar o seguinte:

            backgroundworker.Dispose();
            backgroundworker = null;
            GC.Collect(); //this helps cleans up ram
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top