Domanda

Devo includere un'applicazione .NET in un'altra applicazione .NET come un plugin. L'interfaccia plug-in mi impone di ereditare da una forma di modello. Il modulo viene poi attaccato in un MDI quando il plugin è caricato.

Tutto sta funzionando finora, ma ogni volta che mi iscrivo per trascinare e rilasciare gli eventi, impostare la modalità di completamento automatico per una casella combinata o in varie altre situazioni ottengo la seguente eccezione:

  

... il thread corrente deve essere impostato su   appartamento singolo filo modalità (STA)   prima di chiamate OLE possono essere fatte. Garantire   che la funzione principale ha   STAThreadAttribute segnato su di esso ...

L'applicazione principale è in esecuzione in MTA e sviluppato da un'altra società, quindi non c'è nulla che io possa fare al riguardo.

Ho cercato di fare le cose che causano queste eccezioni in thread STA, ma che non ha risolto il problema.

Qualcuno è stato nella stessa situazione? C'è qualcosa che posso fare per risolvere il problema?

È stato utile?

Soluzione 3

Update: La società ha rilasciato una nuova versione STA. La domanda non è più rilevante.

Altri suggerimenti

Si potrebbe provare a deporre le uova nuovo thread e chiamare CoInitialize con 0 su di esso (appartamento nello stesso filettato) ed eseguire l'applicazione in questo thread. Tuttavia non sarà aggiornare i controlli direttamente all'interno di questa discussione si dovrebbe usare Control.Invoke per ogni modifica dell'interfaccia utente.

Non so se questo sta andando a lavorare per certo, ma si potrebbe provare.

Recentemente ho incontrato questo problema io stesso durante il tentativo di leggere le immagini da una webcam. Quello che ho finito per fare è stato la creazione di un metodo che ha generato un nuovo thread STA, su cui è stato eseguito il metodo single-thread.

Il problema

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 soluzione:. Spostare la logica single-thread al proprio metodo e chiamare questo metodo da un nuovo 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();
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top