Конференция ".Net" » Проблема с потоком
 
  • Александр Иванов © (13.11.06 09:23) [0]
    В новом потоке в первой строке делегата вызывается процедура
    SetMessage("Создание отчета...");



    private void SetMessageCallbackFunc(string msg)
    {
       this.statusTextBox.Text = msg;
    }


    private void SetMessage(string msg)
    {
      SetMessageCallback set = new SetMessageCallback(SetMessageCallbackFunc);
      Invoke(set, msg);
    }



    Но в результате строка появляется только при первом запуске потока. В остальных случаях - добавляется пустая строка. Если запускать в отладке - строка добавляется при каждом запуске, т.е. достаточно факта запуска в режиме отладки. Последующие строки добавляются всегда корректно. В чем может быть ошибка?
  • Lamer@fools.ua © (13.11.06 09:45) [1]
    1. Кода мало, чтобы что-то путное подсказать.
    2. Может вместо Invoke использовать BeginInvoke?
    3. Лично мне нравится такой вот паттерн:
    private void SetMessage(string msg)
    {
       if (this.InvokeRequired)
       {
           this.Invoke(new SetMessageCallback(this.SetMessage), msg);
           // или:
           // this.BeginInvoke(new SetMessageCallback(this.SetMessage), msg);
           return;
       }


       this.statusTextBox.Text = msg;
    }

  • Александр Иванов © (13.11.06 10:09) [2]
    Заменил свой SetMessage на этот и баг иправлен. Хотелось бы понять причину.

    private void SetMessage(string msg)
    {
      if (this.InvokeRequired)
      {
          this.Invoke(new SetMessageCallback(this.SetMessage), msg);
          return;
      }

      this.statusTextBox.Text = msg;
    }
  • Александр Иванов © (13.11.06 10:11) [3]
    > [1] Lamer@fools.ua ©   (13.11.06 09:45)

    Спасибо :)
  • Lamer@fools.ua © (13.11.06 12:57) [4]
    Выдержка из Help'а:

    Controls in Windows Forms are bound to a specific thread and are not thread safe. Therefore, if you are calling a control's method from a different thread, you must use one of the control's invoke methods to marshal the call to the proper thread. This property can be used to determine if you must call an invoke method, which can be useful if you do not know what thread owns a control.

    Note  
    In addition to the InvokeRequired property, there are four methods on a control that are thread safe to call: Invoke, BeginInvoke, EndInvoke and CreateGraphics. For all other method calls, you should use one of these invoke methods when calling from a different thread.


    If the control's handle does not yet exist, InvokeRequired searches up the control's parent chain until it finds a control or form that does have a window handle. If no appropriate handle can be found, the InvokeRequired method returns false.

    This means that InvokeRequired can return false if Invoke is not required (the call occurs on the same thread), or if the control was created on a different thread but the control's handle has not yet been created.

    In the case where the control's handle has not yet been created, you should not simply call properties, methods, or events on the control. This might cause the control's handle to be created on the background thread, isolating the control on a thread without a message pump and making the application unstable.

    You can protect against this case by also checking the value of IsHandleCreated when InvokeRequired returns false on a background thread. If the control handle has not yet been created, you must wait until it has been created before calling Invoke or BeginInvoke. Typically, this happens only if a background thread is created in the constructor of the primary form for the application (as in Application.Run(new MainForm()), before the form has been shown or Application.Run has been called.

    One solution is to wait until the form's handle has been created before starting the background thread. Either force handle creation by calling the Handle property, or wait until the Load event to start the background process.

    An even better solution is to use the SynchronizationContext returned by SynchronizationContext rather than a control for cross-thread marshaling.


    Возможно, проблема в подчёркнутом.
 
Конференция ".Net" » Проблема с потоком
Есть новые Нет новых   [120488   +73][b:0][p:0.001]