Вызов из другого потока

Не могу поверить, что это работает в моем другом приложении, но в этом, имеющем похожую структуру, - нет!

    public string ListAdd
    {
        set
        {
            if (listView1.InvokeRequired)
            {
                this.Invoke((MethodInvoker)delegate
                {
                    listView1.Items.Add(value);
                });
            }
            else
            {
                listView1.Items.Add(value);
            }
        }
    }

Как я это называю:

        var formz = Form.ActiveForm as Form1;
        if (formz != null)
            formz.ListAdd = "asdasdasdasd";

Если я вызываю его из функции, в которой я получаю пакет (я хочу поместить его в listView) по TCP - ничего не происходит, но если я вызываю его в том же классе, где я инициализирую WinSock - он работает.

В чем может быть проблема?

РЕДАКТИРОВАТЬ: Я только что отладил приложение, formz имеет значение null в том месте, где я его вызываю (функция получения). Почему там оно равно нулю, а в другом месте нет?


person Ivan Prodanov    schedule 25.04.2009    source источник
comment
Вы не должны делать такую ​​работу в установщике свойств, подумайте о том, чтобы изменить ее на метод.   -  person Chad Grant    schedule 25.04.2009


Ответы (3)


Я не думаю, что это решит вашу проблему, но думали ли вы об использовании следующего шаблона для вызова? Считаю его гораздо более читабельным. Создайте этот метод расширения.

public static class ControlExtension
{
   public static void ThreadSafeInvoke(this Control control, MethodInvoker method)
   {
      if (control != null)
      {
         if (control.InvokeRequired)
         {
            control.Invoke(method);
         }
         else
         {
            method.Invoke();
         }
      }
   }
}

И затем вы можете выполнять такие вызовы потоковобезопасных методов.

Form form = new Form();

form.ThreadSafeInvoke(() => form.Text = "ThreadSafeInvoke");

Или сразу несколько звонков.

form.ThreadSafeInvoke(() =>                 
{
   form.Text = "ThreadSafeInvoke";
   form.Visible = true;
   form.WindowState = FormWindowState.Maximized;
});

ОБНОВЛЕНИЕ

Итак, проблема явно в Form.ActiveForm возвращении null.

  1. На момент звонка нет активной формы.
  2. У потока нет разрешения на получение активной формы - MSDN утверждает, что UIPermission обязателен.
person Daniel Brückner    schedule 25.04.2009

Если ActiveForm возвращает значение null, возможно, у вас нет активной формы или она не относится к типу Form1. Вы используете «как Form1», поэтому, если у вас есть активная форма Form2, тогда для formz будет установлено значение null.

Можете ли вы передать в функцию formz вместо вызова ActiveForm?

person Steven    schedule 25.04.2009
comment
У меня только одна форма, и я использую async (WSAAsyncSelect ()) для своих подключений. Нет, я не могу назначить Form1 переменной, которая еще не была инициализирована. - person Ivan Prodanov; 25.04.2009
comment
Так что же возвращает Form.ActiveForm? Нулевое значение или форма типа, отличного от Form1? - person Daniel Brückner; 25.04.2009

Проверьте, находитесь ли вы в режиме отладки; В этом случае возвращаемое значение активной формы будет нулевым.

person Anil Mathew    schedule 08.06.2011