Threading problemas com componentes ActiveX do Visual Basic 6.0

Traduções deste artigo Traduções deste artigo
ID do artigo: 241896 - Exibir os produtos aos quais esse artigo se aplica.
Expandir tudo | Recolher tudo

Neste artigo

Sintomas

Ao usar componentes ActiveX do Visual Basic 6.0 em um ambiente multithread, você deve estar ciente dos possíveis problemas a seguir:

DLL ActiveX hospedado em um cliente multithread

  • Violação de acesso dentro MSVBVM60.DLL.
  • Cliente entra em um estado deadlock.
Você poderá ver esses dois sintomas se uma DLL de ActiveX do Visual Basic é hospedada em um ambiente multithread, por exemplo, IIS, MTS ou um cliente de vários segmentos, e a opção de Manter na memória não está habilitada. Para ativar essa opção, siga as etapas abaixo:
  1. No menu Project , selecione Propriedades .
  2. Na guia Geral , certifique-se que o modelo de threading é Apartment thread e marque as caixas de seleção Unattended Execution e Manter na memória * .
  3. Salve o projeto e compilar a DLL.
* Observação A opção de Execução automática não estará disponível se o projeto contém quaisquer elementos de interface do usuário, tais como formulários ou controles. A opção de Manter na memória não está disponível se Unattended Execution não estiver selecionada.

Observação Anterior ao Service Pack 3 para Visual Studio 6.0, era possível obter um antivírus durante o processo de desligamento com reter na memória ativada. Isso foi corrigido no Visual Studio 6.0 service pack mais recente:
http://msdn2.microsoft.com/en-us/vstudio/aa718364.aspx'

Se um projeto UserControl ou ActiveX DLL contém declarações de API, você pode enfrentar travamentos durante o processo/thread desligar ou criação do objeto, mesmo se a caixa de seleção Unattended Execution tem sido selecionado no caso de uma DLL ActiveX. Para solucionar esse problema, você pode usar uma biblioteca de tipos em vez de Declare no Visual Basic. Para obter informações adicionais sobre como usar uma biblioteca de tipos, clique no número % 2 abaixo para ler o artigo % 2 na Base de dados de Conhecimento da Microsoft:
189133COMO: Criar DLL C mais acessíveis para VB com uma biblioteca de tipos

EXE ActiveX acessados por um cliente multithread ou por vários única ou várias threaded clientes

Erro de tempo de execução '7': memória insuficiente e às vezes seguido por um erro de operação do disco.
Erro em tempo de execução '430': classe não oferece suporte automação ou suporte para interface esperada.
Erro em tempo de execução '424': objeto necessário.
Erro em tempo de execução '-2147023170 (800706be)': erro de automação. A chamada de procedimento remoto falhou.
Erro em tempo de execução '-2147287010 (8003001e)': erro de automação. Este é um "Ocorreu um erro de disco durante uma operação de leitura." com base em ErrLook.
Processos do servidor adicionais (ThreadTest.EXE) são criados, mesmo que a propriedade Instancing de Class1 está marcado como MultiUse.
Você pode ver mensagens de erro listadas acima, se você tiver um servidor EXE ActiveX com um pool de segmentos maior do que um (1) e um cliente multithread ou vários única ou várias threaded clientes rapidamente criar e destruir objetos dentro do servidor. Para contornar esse problema, você pode criar uma classe vazia no servidor local e o cliente manter uma referência a ele, como mostrado na seção "Mais informações" abaixo.

Situação

Esse comportamento é por design.No Visual Studio 6 Service Pack 5, se um projeto contiver qualquer classe pública que possui MTSTransactionMode conjunto para algo diferente de 0 , a opção Unattended Execution e Manter na memória opção são automaticamente selecionada.

Mais Informações

Etapas para reproduzir o comportamento

O servidor de criação A:

  1. Crie um projeto ActiveX EXE e renomeá-lo ThreadTest .
  2. No menu Project , selecione Propriedades e na guia Geral , selecione um Pool de segmentos de dois (2).
  3. Adicione o seguinte código à classe padrão (Class1):
    Private strClassName As String
    Public Property Let ClassName(ByVal vData As String)
       strClassName = vData
    End Property
    Public Property Get ClassName() As String
       ClassName = strClassName 
    End Property
    					
  4. Salve e compile o projeto (ThreadTest.EXE).

B: criar o cliente e testar

  1. Inicie um projeto Standard EXE e renomeie-o cliente .
  2. Adicione um botão de comando e uma caixa de texto ao formulário padrão (Form1).
  3. Adicione o seguinte código ao Form1:
    Private Sub Command1_Click()
       Dim i As Long, j As Long
       Dim o As Object
       j = Val(Text1.Text)
       For i = 1 To j
          DoEvents
          Set o = CreateObject("ThreadTest.Class1")
          o.ClassName = i
          Me.Caption = o.ClassName
          Set o = Nothing
       Next
    End Sub
    Private Sub Form_Load()
       Text1.Text = 1000
       Command1.Caption = "Start"
    End Sub
    					
  4. Compile o projeto (Client.EXE).
  5. Iniciar três ou mais instâncias de Client.EXE e pressione o botão Iniciar em cada formulário. Observe que você consulte um ou mais das mensagens de erro acima.

C: implementar a solução alternativa

  1. Abra o projeto ThreadTest.
  2. Adicione outro módulo de classe (Classe2) com nenhum código.
  3. Salve e re-compile projeto (ThreadTest.EXE).
  4. Abra o projeto cliente.
  5. Substitua o código no Form1 com o seguinte:
    Private p As Object
    Private Sub Command1_Click()
       Dim i As Long, j As Long
       Dim o As Object
       j = Val(Text1.Text)
       For i = 1 To j
          DoEvents
          Set o = CreateObject("ThreadTest.Class1")
          o.ClassName = i
          Me.Caption = o.ClassName
          Set o = Nothing
       Next
    End Sub
    Private Sub Form_Load()
       Text1.Text = 1000
       Command1.Caption = "Start"   
       Set p = CreateObject("ThreadTest.Class2")
    End Sub
    Private Sub Form_Unload(Cancel As Integer)
       Set p = Nothing
    End Sub
    					
  6. Salve e re-compile projeto (Client.EXE).
  7. Executar três ou mais instâncias do Client.EXE e pressione o botão Iniciar em cada formulário. Observe que você não deve ver nenhuma mensagem de erro.
Quando um EXE ActiveX com um maior do que um pool de segmentos é acessado por vários clientes através do DCOM, a solução alternativa descrita na parte C da seção "Mais informações" não funciona. Como conseqüência, servidores de EXE de ActiveX do Visual Basic 6.0 não são adequados para servidores DCOM com vários clientes rapidamente criação e destruição de objetos. Se o aplicativo de servidor precisar manipular esse cenário, é altamente recomendável que você use DLLs do ActiveX no MTS em vez disso. Ao criar DLLs do ActiveX para ser hospedado no MTS, você deve fazer se caixas de seleção Unattended Execution e Manter na memória são selecionadas. Essas caixas de seleção e localizado no menu Project , ao escolher Propriedades e selecione a guia Geral .

Não use a propriedade Instancing GlobalMultiUse para uma classe quando você pretende usar o componente ActiveX em MTS ou COM +. A interface para o objeto GlobalMultiUse é armazenados em cache um por tabela baseada em thread e não é liberado até que o thread seja encerrado. Como resultado, se uma chamada vem com um contexto diferente (embora no mesmo thread), ele falhará com RPC_E_WRONG_THREAD. Para usar componentes no MTS e COM +, você deve projetar suas classes de tal forma que os objetos são sem monitoração de estado.

Propriedades

ID do artigo: 241896 - Última revisão: terça-feira, 7 de agosto de 2007 - Revisão: 5.2
A informação contida neste artigo aplica-se a:
  • Microsoft Visual Studio 6.0 Service Pack 3
  • Microsoft Visual Studio 6.0 Enterprise Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
Palavras-chave: 
kbmt kbprb kbthread kbtophit KB241896 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 241896

Submeter comentários

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com