Регистрация в DragDrop не удалась - PullRequest
16 голосов
/ 26 сентября 2008

System.InvalidOperationException: регистрация DragDrop не выполнена добиться успеха. ---> System.Threading.ThreadStateException:

Что означает это исключение? Я получаю это в этой строке, пытаясь добавить панель к панели во время выполнения ...

splitReport.Panel1.Controls.Add(ChartPanel);

Работа в VS2008 C #

Ответы [ 9 ]

35 голосов
/ 02 октября 2008

Это исключение означает, что поток, которому принадлежит Panel (добавляемая Panel), был инициализирован с использованием модели потоков MTA. Система перетаскивания требует, чтобы вызывающий поток использовал модель потока STA (особенно это требует, чтобы COM был инициализирован через OleInitialize). Модели многопоточности - неудачный след COM, предшественника платформы .NET.

Если у вас есть атрибут [STAThread] в вашей основной функции, то основной поток программы уже должен быть STA. Таким образом, наиболее вероятное объяснение состоит в том, что это исключение происходит в другом потоке. Когда возникнет исключение, посмотрите на окно Threads в Visual Studio (Debug | Windows | Threads) и посмотрите, не находитесь ли вы в потоке, отличном от основного потока. Если да, решение, вероятно, так же просто, как установка модели потока для этого нового потока, что вы можете сделать следующим образом (добавьте этот код в поток, где создается элемент управления):

Thread.CurrentThread.SetApartmentState( ApartmentState.STA )

(Thread и ApartmentState являются членами System.Threading)

Этот код должен произойти до того, как вы действительно запустите новый поток. Как отмечает @Tomer, вы также можете декларативно указать это, используя атрибут [STAThread].

Если вы обнаружите, что исключение происходит в основной ветке, отправьте сообщение назад и дайте нам знать, и, возможно, мы сможем помочь вам больше. Трассировка стека во время исключения может помочь отследить проблему.

5 голосов
/ 29 августа 2011
function abc
{
            Thread t = new Thread(new ThreadStart(xyz));
            t.SetApartmentState(ApartmentState.STA);
            t.Start( );    
}
function xyz
{
 the code of Windows form..or whatever which is causing the error
}
3 голосов
/ 20 июня 2016

Добавьте атрибут STAThreadAttribute в метод Main. Этот атрибут необходим, если ваша программа обращается к функциям, связанным с OLE, как это делает класс Clipboard.

[STAThread]

static void Main (строка [] args)

{

}

2 голосов
/ 05 мая 2011

Да, я понимаю, что этот вопрос задавался 2 с половиной года назад. Я попал в это исключение и немного почитал. Я исправил его, но нигде не видел своего решения, поэтому решил опубликовать его там, где кто-то другой мог прочитать.

Одна из возможностей для этого при [STAThread], отмеченном на Main(), заключается в том, если вы запускаете это в потоке, отличном от того, в котором вы начали.

Я только что столкнулся с этим исключением, когда пытался создать и показать новую форму в методе BackgroundWorker.DoWork. Чтобы исправить это, я обернул создание и отображение моей новой формы в метод, а затем вызвал Invoke для этого метода, чтобы он запускался в потоке пользовательского интерфейса. Это сработало, потому что поток пользовательского интерфейса начинался с метода Main() с пометкой [STAThread], как объяснили другие ответы.

2 голосов
/ 05 февраля 2010

Я не уверен, решили ли вы эту проблему или нет. Я только столкнулся с этой проблемой, и я исправил ее, удалив мой bin каталог .

1 голос
/ 19 сентября 2015

Я решил эту ошибку, используя приведенный ниже код ... Я использовал Background Worker и пытался получить доступ к пользовательскому интерфейсу, а фоновый работник ... вот почему ошибка - регистрация DragDrop не удалась. Мы не можем получить доступ к пользовательскому интерфейсу из кода, работающего в фоновом режиме или в потоке.

BeginInvoke((MethodInvoker)delegate
{
//write your code here...

});

Спасибо, Happy Coding ...:

1 голос
/ 10 июня 2014

Самый простой способ:

private void DoSomethingOnGui()
{
    if (this.InvokeRequired)
    {
        this.Invoke((MethodInvoker)delegate
        {
            Safe_DoSomethingOnGui();
        });
    }
    else
    {
        Safe_DoSomethingOnGui();
    }
}
private void Safe_DoSomethingOnGui()
{
    // Do whatever you want with the GUI
}

Вы можете даже передать вещи без проблем:

private void DoSomethingOnGui(object o)
{
    if (this.InvokeRequired)
    {
        this.Invoke((MethodInvoker)delegate
        {
            Safe_DoSomethingOnGui(o);
        });
    }
    else
    {
        Safe_DoSomethingOnGui(o);
    }
}
private void Safe_DoSomethingOnGui(object o)
{
    // Do whatever you want with the GUI and o
}
0 голосов
/ 17 февраля 2015

Я обнаружил эту ошибку, и я вижу, что одна из причин ее появления - использование другого потока, вызывающего MessageBox.Show(this, ...), где это не сделано, инициализировано.

Нам нужно удалить владельца окна сообщения, чтобы устранить ошибку.

0 голосов
/ 27 августа 2013

Я недавно столкнулся с этой ситуацией, [STAThreadAttribute] в моем случае, и я решил эту проблему с помощью метода Invoke , это может быть полезно для вас, ребята, поэтому я поделюсь с небольшим фрагментом кода :

this.Invoke(new InvokeHandler(delegate() 
{
//Your method here!
}));

И InvokeHandler такой делегат:

private delegate void InvokeHandler();
...