ThreadStateException при использовании QueueUserWorkItem в таймере - PullRequest
1 голос
/ 07 июня 2010

В моем приложении WinForms есть исключение ThreadStateException.

Шаг для воспроизведения:

  • Создание простого приложения 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);
        });
    }
    

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

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

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

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

1 Ответ

2 голосов
/ 07 июня 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...