Microsoft
Visual Basic versión 5.0 Service Pack 2,
Notas de la versión
© 1996-1997 Microsoft Corporation
Visual Basic versión 5.0 Service Pack 2 es una actualización a las ediciones Profesional, Empresarial y Control Creation de Visual Basic. La versión Control Creation (disponible en inglés) tiene una actualización independiente. Permite la separación de subprocesos para proyectos de Visual Basic que contienen elementos de la interfaz de usuario, como formularios y controles, y depura varios errores conocidos de Visual Basic 5.0. (Busque VB5FixListSP en el sitio Web Knowledge Base en http://www.microsoft.com/kb/default.asp.)
Aplicar el Service Pack 2 a su copia con licencia de Visual Basic le permite crear controles ActiveX(TM) y documentos ActiveX que funcionan bien en clientes de subprocesos múltiples como Internet Explorer 4.0. Si tiene la edición Profesional o Empresarial de Visual Basic, también puede crear lo siguiente:
|
Esta mejora del modelo de separación de subprocesos es la única característica de Visual Basic versión 5.0 Service Pack 2.
Estas notas de la versión contienen información complementaria a la documentación de Microsoft® Visual Basic® 5.0 incluida en la Ayuda y en los Libros en pantalla. Si desea información adicional, visite el sitio Web de Microsoft Visual Basic en http://www.microsoft.com/vbasic/.
Introducción a los cambios en el modelo de separación de subprocesos
Seleccionar un modelo de subprocesos múltiples para su proyecto
Limitaciones de la característica de Modelo de separación de subprocesos
Convertir proyectos ya existentes
Cambios a la documentación de Visual Basic 5.0
Cambios a "Modelo de separación de subprocesos en Visual Basic"
Cambios a "Diseñar DLL seguras para los subprocesos"
Cambios a "Diseñar componentes de subprocesos múltiples fuera de proceso"
Controles con separación de subprocesos para Internet Explorer 4.0
Crear una DLL segura para los subprocesos con formularios
Crear una aplicación de subprocesos múltiples de prueba
Nota sobre las secuencias de comandos seguras para controles ActiveX
Los proyectos creados con Visual Basic versión 5.0 Service Pack 2 pueden aprovechar el modelo de separación de subprocesos sin necesidad de suprimir elementos visuales como formularios y controles. La aplicación de Service Pack 2 hace que los formularios, controles de usuario, documentos de usuario y diseñadores ActiveX sean seguros de cara a los subprocesos. Service Pack 2 incluye lo siguiente:
|
Nota el código auxiliar para los diseñadores ActiveX es ahora un código de separación de subprocesos seguro para los subprocesos, pero esto no garantiza que un determinado diseñador sea seguro. Si está usando un diseñador de otros proveedores, debe consultar a su proveedor.
Las únicas partes de este documento que se aplican a la edición Control Creation son aquellas que afectan a los proyectos de controles ActiveX seguros para los subprocesos.
Si usa la edición Control Creation para crear controles ActiveX con separación de subprocesos, debe usar un cliente de subprocesos múltiples como Internet Explorer 4.0 para probar el comportamiento de subprocesos múltiples de sus controles. No puede usar la edición Control Creation para crear un cliente de prueba de subprocesos múltiples.
Service Pack 2 cambia las opciones de la ficha General del cuadro de diálogo Propiedades del proyecto. Tras aplicar Service Pack 2, la opción Ejecución desatendida deja de estar activada en el modelo de subprocesos de su proyecto. Puede seleccionar un valor para la opción Modelo de subprocesos sin marcar su proyecto como de Ejecución desatendida.
Para configurar el modelo de subprocesos para un proyecto DLL ActiveX, Exe ActiveX o control ActiveX
|
Nota Cuando cambie el modelo de subprocesos de un proyecto ya existente, ocurrirá un error si el proyecto utiliza controles ActiveX de un único subproceso. Visual Basic impide utilizar controles de un único subproceso en proyectos con separación de procesos, tal y como se describe en Convertir proyectos ya existentes.
Nota Cuando especifica Subproceso por objeto (o un conjunto de subprocesos mayor que uno) para un proyecto Exe ActiveX, sólo los objetos creados externamente se crean en nuevos subprocesos. (Consulte "Diseñar componentes de subprocesos múltiples fuera de proceso" en los Libros en pantalla.) Las opciones Subproceso por objeto y Conjunto de subprocesos no están disponibles para proyectos de DLL ActiveX y controles ActiveX, ya que la creación de procesos está controlada por la aplicación cliente.
Importante Para los usuarios de las ediciones Profesional y Empresarial, las consecuencias de seleccionar Subproceso por objeto o Conjunto de subprocesos se explican en detalle en "Diseñar componentes de subprocesos múltiples fuera de proceso" en los Libros en pantalla.
Service Pack 2 no cambia el funcionamiento de la opción Ejecución desatendida. Dicha opción sigue permitiendo crear componentes que se pueden ejecutar sin la intervención del operador en servidores de red. El único cambio realizado por Service Pack 2 es que la selección de Ejecución desatendida no afecta al modelo de subprocesos de su componente.
Las siguientes limitaciones se aplican a todas las ediciones de Visual Basic.
|
Una vez que haya aplicado Visual Basic versión 5.0 Service Pack 2, podrá agregar separación de subprocesos a sus proyectos ya existentes si cambia la opción Modelo de subprocesos, tal y como se describe en Seleccionar un modelo de subprocesos múltiples para su proyecto, y vuelve a compilar el proyecto. Para muchos proyectos, esto es todo lo que necesitará hacer.
Si un proyecto ya existente de DLL ActiveX, EXE ActiveX o control ActiveX utiliza controles componentes de un único subproceso, intentar cambiar el Modelo de subprocesos a Separación de subprocesos producirá error. Debido al número y a la gravedad de los problemas que los controles ActiveX con un único subproceso causan a los clientes de múltiples subprocesos, Visual Basic no permite utilizarlos en proyectos de componentes ActiveX.
Si tiene un proyecto ya existente que emplea un control de un único subproceso, póngase en contacto con el proveedor para ver si existe una versión con separación de procesos.
Es posible "engañar" a Visual Basic para que utilice un control de un único subproceso en un proyecto con separación de subprocesos si modifica manualmente el archivo .vbp. No lo haga. Entre los problemas que los controles ActiveX de un único subproceso pueden causar cabe citar los siguientes:
|
Importante Los controles de un único subproceso pueden causar estos y otros problemas en cualquier componente o aplicación de subprocesos múltiples que genere, ya sea con Visual Basic o con cualquier otra herramienta de desarrollo.
Los objetos proporcionados por componentes en proceso se crean en subprocesos del cliente; su DLL u OCX no puede crear subprocesos por sí mismo. La primera vez que un subproceso cliente crea una instancia de un objeto proporcionado por su componente, se creará un nuevo apartado para ese subproceso y su subrutina Sub Main se ejecutará para el nuevo apartado. Todos los objetos que proporcione su componente para ese subproceso cliente residirán en el mismo apartado.
Si ha diseñado su componente de forma que todas las instancias de una clase comparten datos globales comunes, esos datos sólo se compartirán ahora entre los objetos que estén en el mismo subproceso. Si hay código global que tiene acceso a una base de datos, ese acceso no ocurrirá de forma separada para cada subproceso.
Por ejemplo, suponga que un cliente de subprocesos múltiples muestra una instancia de su control Widget en un formulario del subproceso A y dos instancias más en un formulario en el subproceso B. Las instancias del control estarán en dos apartados, cada una con una copia de las variables globales. La subrutina Sub Main se ejecutará una vez por cada apartado. Los dos controles del subproceso B compartirán el estado global, separados del estado global del control del subproceso A.
En Cambios al "Modelo de separación de subprocesos en Visual Basic" y en Cambios a "Diseñar DLL seguras para los subprocesos" de este documento, y en los correspondientes temas de los Libros en pantalla de Visual Basic 5.0, se explican otras consideraciones de diseño.
La diferencia más importante entre los componentes de un único subproceso y los componentes con separación de subprocesos fuera de proceso es que todos los datos globales (incluyendo las propiedades del objeto App) se duplican para cada subproceso. Una de las implicaciones de esto es que la subrutina Sub Main se ejecutará cada vez que se cree un nuevo subproceso.
En Cambios a "Modelo de separación de subprocesos en Visual Basic" y en Cambios en "Diseñar componentes de subprocesos múltiples fuera de proceso" en este documento, y en los temas correspondientes de los Libros en pantalla de Visual Basic 5.0, se explican otras consideraciones de diseño para los componentes fuera de proceso.
Los siguientes temas describen cambios específicos en los temas indicados de los Libros en pantalla de Visual Basic 5.0:
Cambios a "Modelo de separación de subprocesos en Visual Basic"
Cambios a "Diseñar DLL seguras para los subprocesos"
Cambios a "Diseñar componentes de subprocesos múltiples fuera de proceso"
Si tiene las ediciones Profesional o Empresarial de Visual Basic, puede encontrar estos temas en los Libros en pantalla mediante el panel Contenido:
Guía de herramientas componentes
Crear componentes ActiveX
Generar componentes de código
Escalabilidad y subprocesos múltiples
Nota El explorador de los Libros en pantalla no se incluye en la edición Control Creation. Los temas indicados anteriormente no se incluyen en las partes de la documentación de Visual Basic 5.0 que se pueden descargar para su uso con la edición Control Creation. Sin embargo, el material sobre la reentrada y el diseño de DLL seguras para los subprocesos contenido en los dos temas siguientes será de interés para los usuarios de la edición Control Creation.
El tema original de los Libros en pantalla explica que Visual Basic mantiene una copia distinta de los datos globales para cada subproceso. Un efecto lateral de esto, que no se menciona en los Libros en pantalla, es que la subrutina Sub Main se ejecuta para cada nuevo apartado (es decir, para cada nuevo subproceso). De lo contrario, no habría ninguna manera de inicializar datos globales para el subproceso. Esto se explica con más detalle en Cambios a "Diseñar DLL seguras para los subprocesos" y en Cambios a "Diseñar componentes de subprocesos múltiples fuera de proceso", más adelante.
Ya no es verdad que los componentes se deben marcar para Ejecución desatendida con el fin de poder usar la separación de procesos. La Ejecución desatendida es ahora una opción independiente en la ficha General del cuadro de diálogo Propiedades del proyecto, tal y como se describió anteriormente en Seleccionar un modelo de subprocesos múltiples para su proyecto.
El tema original indica que cuando se hace una llamada entre subprocesos, el método al que está llamando se protege frente a la reentrada siempre y cuando el método no ceda (por ejemplo, llamando a DoEvents). Es importante hacer notar que un método también cede si se hace una llamada propia entre subprocesos o entre procesos, o si se muestra un formulario.
El tema de los Libros en pantalla se aplica ahora a los proyectos de control ActiveX, así como a los proyectos de DLL ActiveX.
El procedimiento para que un proyecto de DLL ActiveX tenga separación de procesos ha cambiado, tal y como se describe en Seleccionar un modelo de subprocesos múltiples para su proyecto (más arriba). Ya no es necesario suprimir toda la interacción con el usuario (la opción Ejecución desatendida) para tener una DLL con separación de procesos.
Cuando crea una instancia de un formulario en tiempo de ejecución, Visual Basic sigue las mismas reglas que utiliza para otros objetos privados. Es decir, el nuevo formulario se crea en el subproceso donde se ejecuta el operador New. Si crea un formulario implícitamente (por ejemplo, si tiene acceso a una propiedad de formulario mediante una variable que se declaró como As New Form1), el formulario se creará en el subproceso donde se ejecuta el código.
Nota Un caso especial de creación implícita de formulario es el Id. predeclarado (por ejemplo, Form1), una variable de formulario global oculta que Visual Basic mantiene para cada clase de formulario. Puesto que Visual Basic duplica los datos globales para cada apartado, hay un Form1 distinto para cada subproceso. Para evitar confusiones, puede resultar útil evitar el uso de Id. predeclarados en componentes con separación de subprocesos si declara explícitamente su propias variables de formulario.
Nota Duplicar los datos globales significa que una variable declarada como Public en un módulo estándar sólo es global para el subproceso; cada subproceso tiene una instancia de la variable. También significa que las propiedades del objeto App, como App.ThreadID, tienen instancias distintas para cada subproceso.
A diferencia de los formularios, los controles ActiveX son objetos públicos que los formularios cliente pueden crear y utilizar. Una instancia de un control ActiveX siempre reside en el mismo subproceso que el del formulario cliente que la utiliza.
Importante En una DLL con modelo de separación de procesos se crea un nuevo apartado para cada subproceso cliente que solicita objetos proporcionados por la DLL. La primera vez que un subproceso cliente solicita un objeto de ese tipo se ejecuta la subrutina Sub Main para el nuevo apartado. Una DLL no puede crear subprocesos propios.
Ya no es necesario suprimir toda la interacción de usuario (la opción Ejecución desatendida) para tener un Exe de múltiples subprocesos. Las descripciones de Subproceso por objeto y Conjunto de subprocesos (subprocesos circulares) siguen siendo las mismas.
Puede hacer que un proyecto Exe ActiveX tenga separación de subprocesos si abre la ficha General del cuadro de diálogo Propiedades del proyecto y, a continuación, selecciona Subproceso por objeto o Conjunto de subprocesos y establece un tamaño de conjunto mayor que uno.
Al igual que otros objetos privados, los formularios residen en el subproceso donde se crearon. No es posible crear objetos privados mediante la función CreateObject, por lo que no se pueden utilizar para iniciar nuevos subprocesos.
Importante En un ejecutable de subprocesos múltiples, la subrutina Sub Main se ejecuta de manera independiente para cada nuevo subproceso. Visual Basic no proporciona ninguna manera de determina qué subproceso se creó en primer lugar.
Los siguientes temas describen escenarios en los que puede que desee utilizar el modelo de separación de subprocesos.
Controles con separación de subprocesos para Internet Explorer 4.0
Crear una DLL segura para los subprocesos con formularios
Crear una aplicación de subprocesos múltiples de prueba
Internet Explorer 4.0 muestra ventanas mediante varios subprocesos de ejecución. Cuando dos ventanas diferentes de Internet Explorer 4.0 muestran instancias del mismo control ActiveX, el OCX debe proporcionar una instancia a cada subproceso. Si ambas instancias se proporcionan desde el mismo apartado del OCX (como es el caso de Visual Basic 5.0), una de las instancias del control sufrirá una degradación de rendimiento debido a la ordenación entre subprocesos.
Además de la degradación de rendimiento, un control de un único subproceso puede provocar problemas con el enfoque, el cambio con la tecla TAB y las teclas de acceso cuando se utilizan en aplicaciones de subprocesos múltiples.
La compilación de su OCX con Visual Basic versión 5.0 Service Pack 2 mejora el rendimiento y elimina estos problemas. Cada instancia del control utilizada por Internet Explorer 4.0 se ejecuta en el mismo subproceso que la ventana que muestra el control, ya que el OCX puede admitir un apartado diferente para cada subproceso cliente.
Visual Basic versión 5.0 Service Pack 2 incluye nuevas versiones de la mayoría de los controles ActiveX que se suministraban con Visual Basic 5.0. Los controles actualizados ahora tienen el modelo de separación de subprocesos y funcionarán igualmente bien sobre clientes de un único subproceso o de subprocesos múltiples. Entre los controles que todavía son de un único subproceso se incluyen DBGrid, MSChart y los controles heredados que se incluían en el directorio Tools de Visual Basic 5.0.
Una vez que haya aplicado Visual Basic versión 5.0 Service Pack 2, los nuevos proyectos de control ActiveX serán de manera predeterminada del modelo de separación de subprocesos. Puede agregar separación de subprocesos a un control ActiveX ya existente si cambia el modelo de subprocesos, tal y como se describe en Seleccionar un modelo de subprocesos múltiples para su proyecto, y vuelve a compilar el proyecto. Para muchos proyectos de control ActiveX, esto es todo lo que necesita realizar.
Si su proyecto de control ActiveX utiliza controles componentes de un único subproceso, el intento de cambiar el Modelo de subprocesos a Separación de subprocesos provocará un error. Debido al número y a la gravedad de los problemas que causan los controles ActiveX de un único subproceso para los clientes de subprocesos múltiples, Visual Basic no permite utilizarlos como componentes de controles ActiveX con separación de subprocesos. Esto se explica en Convertir proyectos ya existentes.
Si tiene controles ActiveX ya existentes que emplean controles componentes de un único subproceso, póngase en contacto con su proveedor para ver si existe una versión con separación de procesos.
En Convertir proyectos ya existentes se explican otras consideraciones de diseño para los controles ActiveX con separación de procesos.
Ahora puede establecer la opción Modelo de subprocesos a Separación de subprocesos en los proyectos de DLL ActiveX que contienen formularios.
Las DLL con separación de procesos no pueden crear su propios subprocesos; la primera vez que un subproceso cliente solicita un objeto proporcionado por su DLL, se crea un nuevo apartado y se ejecuta la subrutina Sub Main para ese apartado. Todos los objetos públicos que solicite ese cliente residirán en el mismo apartado y compartirán datos globales. Cualquier objeto privado (incluyendo los formularios) creado por los objetos públicos también residirá en el apartado.
Visual Basic no proporciona ninguna manera para que los apartados sean conscientes de que existen otros apartados. Sin embargo, un cliente de subprocesos múltiples podría obtener una referencia a un objeto del subproceso A y pasarla a un objeto del subproceso B. Si su DLL permite esto, debe leer la información sobre la reentrada en la sección "Modelo de separación de subprocesos en Visual Basic" de los Libros en pantalla, y en Cambios a "Modelo de separación de subprocesos en Visual Basic" en este mismo documento.
Importante Los formularios modales mostrados por un subproceso no bloquean la ejecución de código de otros subprocesos y no son modales para los formularios de otros subprocesos. Al mostrar un formulario se produce un control, tal y como ocurre al llamar a DoEvents, y por tanto puede hacer que se vuelva a entrar en el código de un objeto.
Aplicar Service Pack 2 a las ediciones Profesional y Empresarial de Visual Basic le permite crear aplicaciones de subprocesos múltiples de prueba para practicar con sus controles de subprocesos múltiples. Los pasos para crear una aplicación sencilla de subprocesos múltiples son los siguientes:
Importante Para asegurar que cada nuevo objeto MultiUse inicia un nuevo subproceso, debe usar Subproceso por objeto, en lugar de Conjunto de subprocesos.
Sub Main se ejecuta para cada nuevo subproceso. La razón es que Visual Basic mantiene una copia distinta de sus datos globales para cada subproceso (cada apartado). Para poder inicializar los datos globales para el subproceso, debe ejecutarse la subrutina Sub Main. Esto significa que si Sub Main carga un formulario oculto o muestra la interfaz principal de usuario de su aplicación, se cargarán nuevas copias de esos formularios para cada nuevo subproceso que cree.
El código siguiente determina si Sub Main se está ejecutando en el primer subproceso, de forma que pueda cargar el formulario oculto una sola vez y mostrar la interfaz principal de usuario de la aplicación de prueba sólo una vez.
' Valor raíz para el título de ventana oculta Public Const PROC_CAPTION = "ApartmentDemoProcessWindow" Public Const ERR_InternalStartup = &H600 Public Const ERR_NoAutomation = &H601 Public Const ENUM_STOP = 0 Public Const ENUM_CONTINUE = 1 Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long Declare Function EnumThreadWindows Lib "user32" (ByVal dwThreadId As Long, ByVal lpfn As Long, ByVal lParam As Long) As Long ' Controlador de ventana recuperado por EnumThreadWindows. Private mhwndVB As Long ' Formulario oculto que se utiliza para identificar el subproceso principal. Private mfrmProcess As New frmProcess ' Id. de proceso Private mlngProcessID As Long Sub Main() Dim ma As MainApp ' Toma prestado un controlador de ventana que usa para obtener el Id. ' de proceso (vea la devolución de llamada EnumThreadWndMain, más adelante). Call EnumThreadWindows(App.ThreadID, AddressOf EnumThreadWndMain, 0&) If mhwndVB = 0 Then Err.Raise ERR_InternalStartup + vbObjectError, , "Error interno al iniciar el subproceso" Else Call GetWindowThreadProcessId(mhwndVB, mlngProcessID) ' El Id. de proceso hace que el título de la ventana oculta sea único. If 0 = FindWindow(vbNullString, PROC_CAPTION & CStr(mlngProcessID)) Then ' La ventana no se encontró, por lo que es el primer subproceso. If App.StartMode = vbSModeStandalone Then ' Crea un formulario oculto con un título único. mfrmProcess.Caption = PROC_CAPTION & CStr(mlngProcessID) ' El evento Initialize de MainApp (Instancing = ' PublicNotCreatable) muestra el interfaz de usuario principal. Set ma = New MainApp ' (El cierre de la aplicación es más sencillo si no hay ninguna ' referencia global a MainApp; en su lugar, MainApp ' debe pasar Me al formulario de usuariio principal, de forma ' que el formulario evite la terminación de MainApp.) Else Err.Raise ERR_NoAutomation + vbObjectError, , _ "La aplicación no se puede iniciar con Automatización" End If End If End If End Sub ' Función de devolución de llamada utilizada por EnumThreadWindows. Public Function EnumThreadWndMain(ByVal hwnd As Long, ByVal lParam As Long) As Long ' Guarda el controlador de ventana. mhwndVB = hwnd ' La primera ventana es la única que se requiere. ' Detiene la iteración tan pronto como se encuentra una ventana. EnumThreadWndMain = ENUM_STOP End Function ' MainApp llama a esta rutina Sub en su evento Terminate; ' de lo contrario, el formulario oculto impide que ' se cierre la aplicación. Public Sub FreeProcessWindow() Unload mfrmProcess Set mfrmProcess = Nothing End Sub
Importante Esta técnica para identificar el primer subproceso puede que no funcione en futuras versiones de Visual Basic.
Tenga en cuenta que Sub Main no realiza ninguna acción para ningún subproceso posterior al primero. Cuando agregue código que cree objetos MultiUse (para poder iniciar subprocesos siguientes), asegúrese de incluir código para inicializar esos objetos.
EnumThreadWindows se utiliza con una devolución de llamada, EnumThreadWndMain, para encontrar una de las ventanas ocultas que Visual Basic crea para su uso interno. El controlador de esta ventana oculta se pasa a GetWindowThreadProcessId, que devuelve el Id. de proceso. El Id. de proceso se utiliza entonces para crear un título único para la ventana oculta (frmProcess) que carga Sub Main. Los subprocesos siguientes detectan esta ventana y de esta manera pueden indicar que no necesitan crear el objeto MainApp. Estos giros son necesarios ya que Visual Basic no proporciona ninguna manera de identificar el subproceso principal de la aplicación.
La clase MainApp, en su evento Initialize, muestra el formulario principal de la aplicación de prueba. MainApp debe pasar al formulario principal su referencia Me, de manera que el formulario evita que MainApp termine. Desde la interfaz principal de usuario puede crear todos los subprocesos siguientes. Configurar la propiedad Instancing para MainApp como PublicNotCreatable le ayudará a evitar que se muestren dos formularios de interfaz de usuario principal.
Un ejemplo sencillo de una clase MainApp y su formulario asociado (pasos 5 y 6 anteriores) podría tener la apariencia siguiente:
' Código para una clase MainApp. Private mfrmMTMain As New frmMTMain Private Sub Class_Initialize() Set mfrmMTMain.MainApp = Me mfrmMTMain.Caption = mfrmMTMain.Caption & " (" & App.ThreadID & ")" mfrmMTMain.Show End Sub Friend Sub Closing() Set mfrmMTMain = Nothing End Sub Private Sub Class_Terminate() ' Borra la ventana oculta. Call FreeProcessWindow End Sub ' Código para el formulario frmMTMain. Public MainApp As MainApp Private Sub Form_Unload(Cancel As Integer) Call MainApp.Closing Set MainApp = Nothing End Sub
Incluir el Id. de proceso en el título de la ventana oculta permite que se ejecuten varias instancias de la aplicación de prueba sin interferirse entre ellas.
Cuando llama a CreateObject, la instancia de la clase pública que crea estará en un subproceso de la instancia actual de la aplicación. Esto se debe a que CreateObject siempre intenta crear un objeto en la aplicación actual antes de buscar otros componentes Exe que podría proporcionar el objeto.
Puede que encuentre útil exponer el Id. de proceso como una propiedad de sólo lectura del módulo que contiene Sub Main:
'Este código no se requiere para la aplicación de prueba Public Property Get ProcessID() As Long ProcessID = mlngProcessID End Property
Esto permite que cualquier objeto del subproceso obtenga el Id. de proceso si llama a la propiedad ProcessID no cualificada. También puede que encuentre útil exponer una propiedad Boolean IsMainThread de esta forma.
La opción Subproceso por objeto hace que cada objeto público se cree externamente (es decir, que se cree mediante la función CreateObject) para iniciarse en un nuevo subproceso. Para crear un nuevo subproceso, basta con utilizar el Id. de programa (ProgID) de una de sus clases MultiUse:
'Este código no se incluye en la aplicación de prueba Dim tw As ThreadedWindow Set tw = CreateObject("ThreadDemo.ThreadedWindow")
La variable tw contiene ahora una referencia a un objeto de un nuevo subproceso. Todas las llamadas a las propiedades y los métodos de este objeto que se realicen mediante tw estarán sujetas a la carga adicional que supone la ordenación entre subprocesos.
Nota Un objeto creado con el operador New no se crea en un nuevo subproceso. Reside en el mismo subproceso donde se ejecutó el operador New. Vea "Diseñar componentes de subprocesos múltiples fuera de proceso" y "Cómo funciona la creación de objetos en componentes de Visual Basic" de los Libros en pantalla.
Para asegurarse de que MainApp no termina hasta que todos los demás subprocesos han finalizado, puede asignar a cada clase pública una propiedad MainApp. Cuando un objeto crea un objeto MultiUse en un nuevo subproceso, puede pasar al nuevo objeto una referencia al objeto MainApp como parte del proceso de inicialización. (También puede pasar a MainApp una referencia al nuevo objeto, de forma que MainApp tenga un conjunto de referencias a todos los objetos que controlan subprocesos; sin embargo, recuerde que esto creará referencias circulares. Vea "Tratamiento de las referencias circulares" en los Libros en pantalla.)
Si desea que una clase que controla un subproceso muestre un formulario, debe proporcionarle un método Initialize (no se confunda con el evento Initialize) o un método Show que muestre el formulario. No muestre el formulario en el procedimiento de evento Class_Initialize, puesto que esto podría provocar error de temporización al crear instancias de la clase. En una clase muy sencilla, el código para una clase MultiUse ThreadedWindow y su formulario, frmThreadedWindow, podría tener la siguiente apariencia:
'Código para una clase MultiUse ThreadedWindow. Private mMainApp As MainApp Private mfrm As New frmThreadedWindow Public Sub Initialize(ByVal ma As MainApp) Set mMainApp = ma Set mfrm.ThreadedWindow = Me mfrm.Caption = mfrm.Caption & " (" & App.ThreadID & ")" mfrm.Show End Sub Friend Sub Closing() Set mfrm = Nothing End Sub 'Código para el formulario frmThreadedWindow. Public ThreadedWindow As ThreadedWindow Private Sub Form_Unload(Cancel As Integer) Call ThreadedWindow.Closing Set ThreadedWindow = Nothing End Sub
El siguiente miniprograma muestra cómo podría inicializar el objeto ThreadedWindow:
'Código para el formulario principal de la aplicación de prueba (frmMTMain). Private Sub mnuFileNewTW_Click() Dim tw As ThreadedWindow Set tw = CreateObject("ThreadDemo.ThreadedWindow") ' Indica al nuevo objeto que muestre su formulario y ' le pasa una referencia al objeto de la ' aplicación principal. Call tw.Initialize(Me.MainApp) End Sub
Si tiene varias clases que controlan subprocesos, puede hacer que su código sea más genérico mediante la definición de una interfaz IApartment que contenga el método Initialize. Cuando implemente IApartment en cada clase, puede proporcionar el código del método Initialize apropiado para esa clase. El código para la creación de subproceso podría tener la siguiente apariencia:
'Este código no se requiere para la aplicación de prueba Private Sub mnuFileNewObject_Click(Index As Integer) Dim iapt As IApartment Select Case Index Case otThreadedWindow Set iapt = CreateObject("ThreadDemo.ThreadedWindow") ' (otros casos ) End Select ' Código común para inicializar objetos. Call iapt.Initialize(MainApp) End Sub
Nota Puede crear una interfaz IXxxxApartment que sea conocida sólo para la aplicación de subprocesos múltiples si define la interfaz en una biblioteca de tipos distinta. En el proyecto de Exe ActiveX, establezca una referencia a la biblioteca de tipos.
Para asegurar el cierre apropiado de una aplicación de subprocesos múltiples debe hacer un seguimiento de todas las referencias a los objetos MultiUse que utilice para crear y controlar subprocesos.
Defina claramente sus objetivos para la duración del objeto. Por ejemplo, considere el caso de un objeto MultiUse que muestra un formulario. La forma más sencilla de administrar la duración del objeto es hacer que el objeto pase al formulario una referencia Me; el formulario mantiene entonces el objeto vivo. Cuando el usuario cierra el formulario, el evento Unload del formulario debe establecer todas las referencias al objeto MultiUse como Nothing, de forma que el objeto puede terminar y a su vez limpiar su referencia al formulario. (Puede que encuentre útil proporcionar al objeto MultiUse un método Friend que limpie la referencia al formulario y todas las demás referencias internas al objeto; el evento Unload del formulario puede llamar a este método.)
Si el objeto que controla un subproceso crea objetos adicionales en el subproceso mediante el operador New, asegúrese de que limpia las referencias a esos objetos. El subproceso no puede cerrarse hasta que se hayan liberado todas las referencias a objetos que se crearon en el subproceso. Los subprocesos abiertos consumen recursos del sistema.
Puesto que las propiedades y métodos Friend no forman parte de la interfaz pública de una clase, no puede llamarlos desde otro subproceso. Las llamadas de subprocesos cruzados entre objetos se limitan a las propiedades y los métodos declarados como Public.
Si un método de un objeto funciona llamando a DoEvents, mostrando un formulario modal o haciendo una llamada secundaria a un objeto de otro subproceso, una segunda llamada puede entrar en el código del método antes de que se complete la primera llamada. Si ese método usa o cambia valores de propiedad o variables de módulo, esto podría dar lugar a un estado interno no válido del objeto. Para protegerse frente a la reentrada, puede hacer lo siguiente:
|
Visual Basic no proporciona ninguna manera de bifurcar la ejecución; es decir, hacer que un subproceso inicie una llamada a un método en un nuevo subproceso y reanude inmediatamente el procesamiento en el subproceso original. Puede simular este comportamiento en su aplicación de prueba si hace que la llamada al método original active un cronómetro y después vuelva inmediatamente. Cuando ocurra el evento del cronómetro, puede desactivar el cronómetro y realizar el procesamiento asíncrono. Esta técnica se explica en "Devoluciones de llamada y eventos asíncronos" en los Libros en pantalla, y se demuestra en los Libros en pantalla (vea "Crear un componente Exe ActiveX") y en la aplicación de ejemplo Coffee.
Debe compilar la aplicación de prueba de subprocesos múltiples para poder probar el componente con separación de subprocesos, ya que el entorno de desarrollo de Visual Basic no admite actualmente varios subprocesos de ejecución. Si tiene Visual Studio, puede que encuentre útil compilar la aplicación de prueba con la información para depuración de código nativo, de forma que pueda utilizar el depurador de Visual Studio.
Dos de los controles con separación de subprocesos que se incluyen con Visual Basic versión 5.0 Service Pack 2, el control Common Dialog y el control Toolbar, admiten ahora la interfaz IObjectSafety de ActiveX. Cuando se utilizan estos controles en un entorno donde se exigen secuencias de comandos seguras, como en Internet Explorer, se marcan como Seguros para secuencias de comandos; sin embargo, ciertas características de estos controles estarán desactivadas para poder calificarlos como seguros para secuencias de comandos:
|
En Visual Basic versión 5.0 Service Pack 2 se incluyen los siguientes archivos:
comct232.ocx comct232.dep comctl32.ocx comctl32.dep comdlg32.ocx comdlg32.dep dbgrid32.ocx dbgrid32.dep dblist32.ocx dblist32.dep mci32.ocx mci32.dep mscomm32.ocx mscomm32.dep msflxgrd.ocx msflxgrd.dep msinet.ocx msinet.dep msmapi32.ocx msmapi32.dep |
msmask32.ocx msmask32.dep msrdc20.ocx msrdc20.dep msrdo20.dll msrdo20.dep msstkprp.dll mswinsck.ocx mswinsck.dep picclp32.ocx picclp32.dep richtx32.ocx richtx32.dep sysinfo.ocx sysinfo.dep tabctl32.ocx tabctl32.dep vb5.exe vba5.dll vb5ide.dll |
msvbvm50.dll c2.exe asycfilt.dll oleaut32.dll olepro32.dll stdole2.tlb setupwiz.exe vb5dep.ini setup1.bas setup1.exe vb5sp2.htm vb5sp2.wri readme.wri mscdrun.dll mscdrun.dep mscondes.dll msctles.dll cmdlges.dll flxgdes.dll msprpes.dll |
vb5es.dll |
Pulsa este link si quieres ver el resultado de buscar: VB5FixlistSP2 en http://www.microsoft.com/kb