backgroundworker abort
-
03-07-2019 - |
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.
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