Multithreading: Criação de segmentos de trabalho
Um segmento de trabalho normalmente é usado gerenciar tarefas em segundo plano que o usuário não deve ter que aguardar para continuar a usar o aplicativo.As tarefas como impressão do novo cálculo e do plano de fundo são bons exemplos de segmentos de trabalho.Este tópico detalha as etapas necessárias para criar um segmento de trabalho.Os tópicos incluem:
Iniciando o segmento
Implementando a função de controle
Exemplo
Criar um segmento de trabalho é uma tarefa relativamente simples.Apenas duas etapas são necessárias para obter a execução de segmento: implementando a função de controle e iniciar a thread.Não é necessário derivar uma classe de CWinThread.Você pode derivar uma classe se uma versão especial de CWinThread, mas não for necessário para a maioria de segmentos de trabalho simples.Você pode usar CWinThread sem alteração.
Iniciando o segmento
Há duas versões sobrecarregadas de AfxBeginThread: um que só pode criar segmentos de trabalho, e um que pode criar segmentos e segmentos de trabalho da interface do usuário.Para iniciar a execução do segmento de trabalho usando a primeira sobrecarga, chame AfxBeginThread, fornecendo as seguintes informações:
O endereço da função de controle.
O parâmetro a ser passado para a função de controle.
(Opcional) a prioridade desejada do segmento.O padrão é prioridade normal.Para obter mais informações sobre níveis de prioridade disponíveis, consulte SetThreadPriority em Windows SDK.
(Opcional) o tamanho desejado de pilha para o segmento.A opção é a pilha do mesmo tamanho que o segmento criador.
CREATE_SUSPENDED (opcional) se você deseja que o segmento a ser criado em um estado suspenso.O padrão é 0, ou inicie o segmento normalmente.
(Opcional) os atributos de segurança desejados.O padrão é o mesmo acesso que o segmento pai.Para obter mais informações sobre o formato desta informação de segurança, consulte SECURITY_ATTRIBUTES em Windows SDK.
AfxBeginThread cria e inicializa um objeto de CWinThread para você, inicia o, e retorna seu endereço para que você possa pode posteriormente.Verifica são feitas durante qualquer procedimento para certificar-se que todos os objetos são desalocados corretamente se qualquer parte da falha de design.
Implementando a função de controle
A função de controle define o segmento.Quando essa função é inserida, inicia o segmento, e quando termina, o segmento finalizam.Essa função deve ter o protótipo seguir:
UINT MyControllingFunction( LPVOID pParam );
O parâmetro é um único valor.O valor que a função recebe neste parâmetro é o valor que foi passado para o construtor quando o objeto de segmento foi criado.A função de controle pode interpretar o valor de qualquer forma que escolha.Pode ser tratado como um valor escalar ou um ponteiro para uma estrutura que contém vários parâmetros, ou pode ser ignorada.Se o parâmetro se refere a estrutura, a estrutura pode ser usada para transmitir não apenas dados do chamador para o segmento, mas também para passar dados suportar de segmento para o chamador.Se você usar uma estrutura para passar dados de volta para o chamador, o segmento de notificar o chamador quando os resultados estão prontos.Para obter informações sobre a comunicação de thread de trabalho para o chamador, consulte Multithreading: Dicas de programação.
Quando a função finaliza, deve retornar um valor de UINT que indica a razão para o encerramento.Normalmente, esse código de saída é 0 para indicar o êxito com outros valores que indicam diferentes tipos de erros.Este é puramente dependente de implementação.Alguns segmentos podem manter as contagens do uso de objetos e retornar o número atual dos usos do objeto.Para ver como os aplicativos podem recuperar esse valor, consulte Multithreading: Segmentos de terminação.
Há algumas restrições em que você pode fazer em um programa com gravado com a biblioteca MFC.Para obter descrições dessas restrições e outros dicas sobre o uso de threads, consulte Multithreading: Dicas de programação.
Exemplo da função de controle
O exemplo a seguir mostra como definir uma função de controle e usá-la de outra parte do programa.
UINT MyThreadProc( LPVOID pParam )
{
CMyObject* pObject = (CMyObject*)pParam;
if (pObject == NULL ||
!pObject->IsKindOf(RUNTIME_CLASS(CMyObject)))
return 1; // if pObject is not valid
// do something with 'pObject'
return 0; // thread completed successfully
}
// inside a different function in the program
.
.
.
pNewObject = new CMyObject;
AfxBeginThread(MyThreadProc, pNewObject);
.
.
.