/ / Muitas tarefas curtas no gui-c #, multithreading, interface de usuário, .net-4.0, backgroundworker

Muitas tarefas curtas no gui - c #, multithreading, user - interface, .net - 4.0, backgroundworker

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 № 1

BackgroundWorker 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.