C # Потоки и формы: NotSupportedException - Использовать Control.Invoke? - PullRequest
1 голос
/ 08 февраля 2011

Я пытаюсь запустить приложение как минимум с двумя потоками: одна форма для пользовательского интерфейса и один или несколько рабочих потоков.Они совместно читают / пишут из статического класса через ряд других классов.

Вот почему я передаю экземпляр рабочего класса в форму отображения.Я думаю, именно поэтому для меня это идет не так:

 public class CoCoon
 {
    private Screen displayForm;
    private Worker worker; 

    public ThreadedApp()
    {
        worker = new Worker (1024);
        displayForm = new Screen(worker);
    }

    public void Run()
    {
        //thread 1: display form
        Thread screenThread = new Thread(() => Application.Run(displayForm));

        //thread 2: background worker
        Thread workerThread = new Thread(worker.Run) {IsBackground = true};

        screenThread.Start();

        Thread.Sleep(1000); //if I don't wait a while, I get an ObjectDisposedException!

        workerThread.Start();

    }

Потоки и объекты инициируются просто отлично, но как только после обработки метода Form_Load в Application.Run выдается ошибка.(displayForm) строка выше.Это NotSupportedException, с замечанием, что я должен использовать Control.Invoke.Но я не уверен, что понимаю, потому что я не позволяю темам, кроме формы отображения, использовать элементы управления на ней.

Я новичок в потоках.Может ли кто-нибудь помочь мне на моем пути?Спасибо!

PS: Одна деталь - я разрабатываю это для платформы Windows Mobile.

РЕДАКТИРОВАТЬ После популярного запроса настоящим Stack Trace

 at Microsoft.AGL.Common.MISC.HandleAr(PAL_ERROR ar)\r\n   at    
 System.Windows.Forms.Control.get_Visible()\r\n   at 
 System.Windows.Forms.Form._SetVisibleNotify(Boolean fVis)\r\n   at  
 System.Windows.Forms.Control.set_Visible(Boolean value)\r\n   at 
 System.Windows.Forms.Application.Run(Form fm)\r\n   at
 CoCoonWM6.CoCoon.<Run>b__1()\r\n

Ответы [ 3 ]

2 голосов
/ 08 февраля 2011

Я рекомендую, чтобы у вас был только один поток пользовательского интерфейса, основной поток. Вы можете использовать другие потоки для фоновых операций, но сохраняйте все элементы пользовательского интерфейса в основном потоке.

Поток пользовательского интерфейса должен быть единственным, вызывающим Application.Run. WinForms предъявляет другие требования к потоку пользовательского интерфейса (например, STA), и они удовлетворяются основным потоком. Теоретически WinForms может поддерживать два потока пользовательского интерфейса, но это непросто.

Обычно я рекомендую другие формы синхронизации, когда вам нужно обновить элементы управления пользовательского интерфейса из фонового потока - TaskScheduler или SynchronizationContext. К сожалению, на мобильной платформе ваш единственный вариант - Control.Invoke.

1 голос
/ 08 февраля 2011

Проверьте трассировку стека для исключения (и опубликуйте его).Вы почти наверняка получаете доступ к некоторым Control из рабочего потока.

Таким образом вы можете изменить доступ к элементу управления (в данном примере метке) после того, как вы обнаружите, где вы получаете доступ к элементам управления из потоков, не являющихся пользовательским интерфейсом.:

if (label13.InvokeRequired)
{
  ChangeTextDelegate changeText = new ChangeTextDelegate(anyChangeTextMethod);
  label13.Invoke(changeText, new object[] { newText });
}
else
{
  label13.Text = newText;
}
0 голосов
/ 08 февраля 2011

Похоже, вы пытаетесь использовать элементы графического интерфейса в фоновом потоке.Это объясняет, почему вы должны вызывать Sleep (в противном случае форма и ее элементы управления не завершают загрузку, прежде чем пытаться их использовать), а также исключение Control.Invoke (вы не можете использовать элементы GUI из неПользовательский интерфейс).См. Документы для Control.Invoke , чтобы узнать, как его использовать.

Поскольку у вас нет BackgroundWorker и Px в CF, вы действительно вынуждены использоватьнепосредственно к потокам - хотя ThreadPool , вероятно, в большинстве случаев будет лучше, чем создание новых потоков.

...