2014-11-01 1 views
-1

Я хочу написать текст в текстовое поле. Чтобы иметь возможность делать это из разных потоков, я вызываю статический метод, который вызывает нестатический метод, который содержит вызов и текстовое поле. При этом. Я получаю сообщение об ошибке, что он не может вызывать до тех пор, пока не будет установлен дескриптор Windows, поэтому я его установлю. Моя проблема в том, что позицияInvoke looping/crashing

if (!this.IsHandleCreated) 
    this.CreateHandle(); 

ниже в коде только один, где моя программа не рухнет, но теперь это зацикливание (indefinetly) только код BeginInvoke, но на самом деле не текстовый параметр код ниже. Что я делаю не так?

Код:

private void ActualLog(string input) 
     { 
      var currentForm = form as Main; 

      if (!this.IsHandleCreated) 
       this.CreateHandle(); 
      if (currentForm.txtServerLog.InvokeRequired) 
      { 
       this.BeginInvoke(new Action<string>(ActualLog), new object[] { input }); 
       return; 
      } 
      else 
      { 
       currentForm.txtServerLog.Text += input + "\r\n"; 
       currentForm.txtServerLog.Refresh(); 
      } 
     } 

     public static void Log(string input) 
     { 
      Main main = new Main(); 
      main.ActualLog(input); 
     } 

С моей темы, я бы назвал Log("Any String");

ответ

1

Насколько я могу судить, ваш бесконечный цикл потому, что всякий раз, когда txtServerLog имеет InvokeRequired как истинные, вы вызываете Действие, которое передает ActualLog как действие. По сути, каждый раз, когда вы попадаете на этот условный путь, вы снова возвращаетесь из ActualLog. Представьте себе, если вы вынули все другой код в методе и только что:

private void ActualLog(string input) 
{ 
     ActualLog(input); 
} 

я могу отсутствовать некоторые морщины, но я уверен, что это именно то, что вы здесь делаете. Учитывая, что в случае, когда txtServerLog требует, чтобы вы вызывали команды, которые вы никогда не делаете, чтобы изменить это состояние, вы просто собираетесь навсегда зацикливаться.

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

Итак, пример:

private void UpdateTextBox(string input) 
{ 
    currentForm.txtServerLog.Text += input + "\r\n"; 
    currentForm.txtServerLog.Refresh(); 
} 

и ваша функция ActualLog:

private void ActualLog(string input) 
{ 
    var currentForm = form as Main; 

    if (!this.IsHandleCreated) 
    { 
     this.CreateHandle(); 
    } 
    if (currentForm.txtServerLog.InvokeRequired) 
    { 
     this.Invoke(new Action<string>(UpdateTextBox), new object[] { input }); //Make sure to use Invoke, not BeginInvoke 
     return; 
    } 

    UpdateTextBox(input); 
} 

Имейте в виду, что если вы вернетесь на if-состоянии и не имеют еще-если, нет никакой функциональной причины иметь ветку else - вы можете просто включить их после блока if.

Точка о коде, который вы передаете, вы на самом деле не вызываете Log() внутри него, поэтому я не уверен, почему он там, или он имеет отношение к вашим проблемам.

+1

@JanH. Я не уверен на 100%, что вы пытаетесь сделать, но я включил образец выше. – furkle

+0

Спасибо! При использовании Invoke вместо BeginInvoke в вашем примере это работает. Дело в двух функциях состояло именно в том, чтобы я мог вызвать Log() из annother Thread, поскольку Invoke не разрешен в статической функции (поэтому я просто ставил его в нестационарную и называет его статическим). Но спасибо anyways :) –

+0

@JanH. Ах, я трачу больше времени на WPF, чем на WinForms, поэтому я немного ржавчу в разграничении Invoke/BeginInvoke. Рад, что это помогло! – furkle