none
Многопоточный запуск RRS feed

  • Вопрос

  • Задача - после инициации очередной формы запустить метод Work, принадлежащий этой форме, 
    и перейти к инициации следующей формы.
    В приведенном коде метод Start благополучно отрабатывает, но до метода Work дело не доходит вообще.
    Что здесь не так? 

    private void Init ()
    { for (int i=0;i<10;i++)
    { string formName=i.ToString();
    StockFormDct.Add ( formName, new form() );
    } }
    public partial class form : Form
    { public form ()  { Start(); }
    public void Start ()  { BeginInvoke((Action) ( ()=> { Work(); })); }
    public void Work()  { SomeEvent.WaitOne(); }
    }

    27 февраля 2012 г. 6:27

Ответы

  • Создавайте новый терд и запускайте метод Word уже в нем, или получайте тред из пула потоков и передавайте на выполнение ему метод Work.

    Если что-либо требуется обновить на форме, то используйте control.Invoke, у вас же WindowsForm?


    Для связи [mail]

    • Помечено в качестве ответа QazRdx 27 февраля 2012 г. 22:04
    27 февраля 2012 г. 10:20
  • Да, главный поток, в котором запускается UI и все приложение. В нем должен происходить BeginInvoke, в противном случае он не вызовется. Вы делаете ожидание в отдельном потоке, поэтому BeginInvoke в нем вызывать не получится напрямую. Зато его можно вызвать у элемента управления, как написал ниже Дмитрий, или у Dispatcher-а (правда если у вас WPF приложение).
    • Помечено в качестве ответа QazRdx 27 февраля 2012 г. 22:06
    27 февраля 2012 г. 12:40
    Отвечающий

Все ответы

  • BeginInvoke не сработает если вы запускаете его не в UI потоке. Тут не совсем понятно зачем он вам нужен (BeginInvoke)?
    27 февраля 2012 г. 7:34
    Отвечающий
  • Нужно запустить Work, метод обработки сообщения. Этот метод запускается при активизации формы и ждет соответствующего события.
    По получении этого события метод Work активизируется, отрабатывает и снова ожидает следующего аналогичного события для очередного запуска. Sorry, метод Work выглядит слегка иначе -
    public void Work () { _1:; SomeEvent.WaitOne(); SomeWork(); goto _1; }
    Если не BeginInvoke, то что?
    Это продолжение темы 

    http://social.msdn.microsoft.com/Forums/ru-RU/programminglanguageru/thread/c2997b87-1f04-409d-a99f-8310a4419535

    27 февраля 2012 г. 7:59
  • Вызывайте Work() напрямую. Если в нем что-то производится над UI, то передавайте в метод Start Dispatcher и у него вызывайте BeginInvoke.
    27 февраля 2012 г. 8:45
    Отвечающий
  • UI - это...? Я понял так, что это что-то, связанное с главным потоком.
    Более подробная версия того, что мне нужно.
    После инициации всех форм в главном потоке формируются 
    события, связанные с соответствующими формами и сообщения для этих форм.
    Во всех формах Start отрабатывает, но в Work ничего не попадает.
    Напрямую Work вызывать не получается, первая же форма, начинает ждать "свое" событие,
    и дальше не пускает.

    public static Dictionary<string,EventWaitHandle>EventDct=new Dictionary<string,EventWaitHandle>();
    public Dictionary<string,form>FormDct=new Dictionary<string,form>();
    public Random R=new Random();
    int N=5;
    public static string Msg;
    private void Init ()
    { for (int i=0;i<N;i++)
      { string formName=i.ToString();
         EventDct.Add(formName,new EventWaitHandle(false,EventResetMode.AutoReset));
         FormDct.Add(formName,new form(formName,i));
       }
       for (int i=0;i<N;i++) 
       { string fN=i.ToString();
         FormDct[fN].BeginInvoke((Action)(()=>{FormDct[fN].Start();}));
       }
       while (true)
       { string s=R.Next(0,N-1).ToString(); Msg=s+"_Msg";
          EventDct[s].Set();
     } }
     public partial class form : Form
     { public form(string T,int I )
        { Text = T;
           tbData=new TextBox();
           Controls.Add(tbData);
           Show();
        }
        public TextBox tbData;
    //  public void Start(){ BeginInvoke((Action)(()=>{Work();})); }
        public void Start(){ Work(); }
        public void Work()
        {_1:;EventDct[Text].WaitOne(); 
            tbData.Text=Msg; 
            goto _1;
     }}}


    • Изменено QazRdx 27 февраля 2012 г. 10:16
    27 февраля 2012 г. 10:14
  • Создавайте новый терд и запускайте метод Word уже в нем, или получайте тред из пула потоков и передавайте на выполнение ему метод Work.

    Если что-либо требуется обновить на форме, то используйте control.Invoke, у вас же WindowsForm?


    Для связи [mail]

    • Помечено в качестве ответа QazRdx 27 февраля 2012 г. 22:04
    27 февраля 2012 г. 10:20
  • Да, главный поток, в котором запускается UI и все приложение. В нем должен происходить BeginInvoke, в противном случае он не вызовется. Вы делаете ожидание в отдельном потоке, поэтому BeginInvoke в нем вызывать не получится напрямую. Зато его можно вызвать у элемента управления, как написал ниже Дмитрий, или у Dispatcher-а (правда если у вас WPF приложение).
    • Помечено в качестве ответа QazRdx 27 февраля 2012 г. 22:06
    27 февраля 2012 г. 12:40
    Отвечающий
  • Всем большое спасибо! Получилось с пулом потоков!
    27 февраля 2012 г. 22:07