ThreadStateException при использовании QueueUserWorkItem в Таймере

У меня есть ThreadStateException в моем приложении WinForms.

Шаг для репродуцирования:

  • Создайте простое приложение winforms
  • Добавьте таймер
  • В событии щелчка сделайте:

    timer1.Interval = 1000;
    timer1.Tick += timer1_Tick;
    timer1.Start();
    

    с

    void timer1_Tick(object sender, EventArgs e)
    {
        ThreadPool.QueueUserWorkItem(delegate
        {
            StringCollection paths =
                new StringCollection { @"c:\my.txt", @"c:\my.png" };
            Clipboard.SetFileDropList(paths);
        });
    }
    

Исключение говорит мне:

Текущий поток должен быть установлен на режим единственной квартиры потока (STA), прежде чем вызовы OLE смогут быть выполнены. Удостоверьтесь, что Вашей Основной функции отметили STAThreadAttribute на нем.

Но основное уже имеет [STAThread] атрибут.

Как решить его?

1
задан dtb 7 June 2010 в 14:27
поделиться

1 ответ

Здесь важен метод Thread.SetApartmentState (). Буфер обмена - это COM-объект, он не ориентирован на многопоточность. Есть много функций Windows, которые ведут себя подобным образом, например, Drag + Drop и диалоги оболочки, такие как OpenFileDialog.

Вы не можете установить состояние квартиры для потока пула потоков, это всегда MTA (Многопоточная квартира).Вы можете использовать обычный поток, но дополнительное требование STA заключается в том, что вы также качаете цикл сообщений (Application.Run). Это возвращает вам ту же проблему: вы не можете блокировать или долго выполнять код.

Простое решение - делать то, что требует много времени для выполнения в потоке. И сделайте вызов буфера обмена из потока пользовательского интерфейса. Используйте Control.BeginInvoke () или, лучше, BackgroundWorker.RunWorkerCompleted.

2
ответ дан 3 September 2019 в 00:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: