Quando devo fazer muitas tarefas curtas, que estão cooperando com a GUI, devo usar outra BackgroundWorker
para cada tarefa ou alguma outra solução?
EDITAR
Quero dizer, atualize cada célula no datagridview (200 linhas x 50 colunas) a cada 5 segundos. Cada célula armazena a imagem.
Respostas:
2 para resposta № 1BackgroundWorker
seria mais adequado para tarefas de longa duração, você quer algo como Grupo de discussão. Aqui está um exemplo muito grosseiro:
QueueUserWorkItem
permite que você especifique um método worker e passe um objeto para esse método para trabalhar.
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), object);
Então você teria o seu DoWork
método onde toda a mágica acontece:
public void DoWork(object sender)
{
object s = (object)sender;
this.Invoke(new ThreadDone(ReportProgress), result);
}
Observe a chamada para this.Invoke(new TaskDone(ReportProgress));
Isso chama com segurança o código em execução no thread principal para atualizar sua interface do usuário com dados processados de DoWork
. Isso é feito por meio de um delegado particular:
private delegate void ThreadDone(object yourObject);
Que chamaria:
private void ReportProgress(object yourObject)
{
//update UI
}
Você também pode usar isso para verificar quando a tarefa é concluída, mantendo o controle de um Interlocked
objeto de contador, e.
foreach (string s in strings)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), s);
Interlocked.Increment(ref workItems);
}
E então decrementando o workItems
quando um único segmento é concluído e fazer uma verificação simples para quando workItems == 0
Interlocked.Decrement(ref workItems);
if (workItems == 0)
{
this.Invoke(new TaskDone(WorkComplete));
}
Espero que isto ajude.
2 para resposta № 2
Quando estou lidando com muitas tarefas pequenas, tenho a tendência de descobrir ThreadPool
é uma boa maneira de lidar com eles. Você pode enviar um delegado em um segmento de segundo plano como:
ThreadPool.QueueUserWorkItem(new WaitCallback(MyThreadProc));
Você também pode passar um objeto para o segmento como "estado", considere um delegado que leva um objeto como um parâmetro. Você poderia chamar isto:
ThreadPool.QueueUserWorkItem(new WaitCallback(MyThreadProc), state);
Onde estado é algum objeto que seu segmento sabe como lidar.
Editar: UMA ThreadPool
abordagem deve funcionar muito bem para o seu cenário. Apenas certifique-se de que qualquer código que altere sua GUI tenha que ser invocado no thread da GUI, ou você obterá algumas exceções cross-thread.