Question

Je dois inclure une application .NET dans une autre application .NET en tant que plug-in. L'interface du plugin me oblige à hériter d'un modèle de formulaire. La forme est ensuite fixé dans un MDI lorsque le module est chargé.

Tout fonctionne à ce jour, mais chaque fois que je me inscrire à glisser-déposer des événements, réglez le mode de saisie semi-automatique pour un combobox ou à d'autres situations que je reçois l'exception suivante:

  

... le thread courant doit être réglé sur   simple appartement de fil en mode (STA)   avant que les appels OLE peuvent être faites. Assurer, garantir   que votre fonction principale a   STAThreadAttribute marqué sur elle ...

La principale application est en cours d'exécution dans le MTA et développé par une autre société, donc il n'y a rien que je puisse faire à ce sujet.

J'ai essayé de faire les choses qui causent ces exceptions dans les discussions STA, mais cela ne résout pas le problème non plus.

Quelqu'un at-il été dans la même situation? Est-ce que je peux faire pour résoudre le problème?

Était-ce utile?

La solution 3

Mise à jour: La société a publié une nouvelle version STA. La question n'est plus pertinent.

Autres conseils

Vous pouvez essayer de reproduire nouveau thread et appeler CoInitialize avec 0 sur elle (aparment filetée) et exécutez votre application dans ce fil. Cependant, vous ne serez pas à mettre à jour les contrôles directement dans ce thread, vous devez utiliser Control.Invoke pour chaque modification de l'interface utilisateur.

Je ne sais pas si cela va fonctionner pour vous, mais vous pouvez l'essayer.

Je me suis récemment tombé sur ce problème tout en essayant de lire les images d'une caméra Web. Ce que je fini par faire a été la création d'une méthode qui a donné naissance à un nouveau thread STA, sur lequel la méthode unique thread a été exécuté.

Le problème

private void TimerTick(object sender, EventArgs e)
{
   // pause timer
   this.timer.Stop();

        try
        {
            // get next frame
            UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraGetFrame, 0, 0);

            // copy frame to clipboard
            UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraCopy, 0, 0);

            // notify event subscribers
            if (this.ImageChanged != null)
            {
                IDataObject imageData = Clipboard.GetDataObject();

                Image image = (Bitmap)imageData.GetData(System.Windows.Forms.DataFormats.Bitmap);

                this.ImageChanged(this, new WebCamEventArgs(image.GetThumbnailImage(this.width, this.height, null, System.IntPtr.Zero)));
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error capturing the video\r\n\n" + ex.Message);
            this.Stop();
        }
    }
   // restart timer
   Application.DoEvents();

   if (!this.isStopped)
   {
      this.timer.Start();
   }
}

La solution:. Déplacer la logique unique de fil à sa propre méthode, et appeler cette méthode à partir d'un nouveau thread STA

private void TimerTick(object sender, EventArgs e)
{
    // pause timer
    this.timer.Stop();

    // start a new thread because GetVideoCapture needs to be run in single thread mode
    Thread newThread = new Thread(new ThreadStart(this.GetVideoCapture));
    newThread.SetApartmentState(ApartmentState.STA);
    newThread.Start();

    // restart timer
    Application.DoEvents();

    if (!this.isStopped)
    {
        this.timer.Start();
    }
}

/// <summary>
/// Captures the next frame from the video feed.
/// This method needs to be run in single thread mode, because the use of the Clipboard (OLE) requires the STAThread attribute.
/// </summary>
private void GetVideoCapture()
{
    try
    {
        // get next frame
        UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraGetFrame, 0, 0);

        // copy frame to clipboard
        UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraCopy, 0, 0);

        // notify subscribers
        if (this.ImageChanged!= null)
        {
            IDataObject imageData = Clipboard.GetDataObject();

            Image image = (Bitmap)imageData.GetData(System.Windows.Forms.DataFormats.Bitmap);

            // raise the event
            this.ImageChanged(this, new WebCamEventArgs(image.GetThumbnailImage(this.width, this.height, null, System.IntPtr.Zero)));
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error capturing video.\r\n\n" + ex.Message);
        this.Stop();
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top