【问题标题】:Controls on another thread控制另一个线程
【发布时间】:2014-02-24 13:06:39
【问题描述】:

我需要在另一个线程上使用控件。我知道我需要调用它们,但不知道如何调用。这是我的代码:

Thread threadWriteLog = new Thread(new ThreadStart(this.WriteLog));
threadWriteLog.Start();

private void WriteLog()
    {
        date = DateTime.Now;
        using (StreamWriter swLog = new StreamWriter(String.Format("{0}\\RoutesLogs\\{1}.log", Settings.Instance.Paths.SDCard, textName), true))         //zapisovanie logu
        {
            if (btnStartPause.Text == "Start Recording")
                swLog.WriteLine(String.Format("Route start: {0}", date.ToString(format)));
            else if (btnStartPause.Text == "Pause Recording")
                swLog.WriteLine(String.Format("Route pause: {0}", date.ToString(format)));
            else if (btnStartPause.Text == "Resume Recording")
                swLog.WriteLine(String.Format("Route resume: {0}", date.ToString(format)));
        }
    }

你能给我写一个解决代码吗?

【问题讨论】:

  • 您也可以使用枚举RecordingStatus 作为表单中的类变量,而不是尝试访问按钮的文本。并且作为一个副作用,可以消除拼写错误的机会。
  • C.Evenhuis 的建议也会否定调用主线程的使用。
  • 我将 btn.text 保存到主线程上的字符串中,现在我在另一个线程上比较该字符串。工作正常,但我想看看如何调用控件,这对我很有用。谢谢
  • 这完全是个坏主意。本地化您的应用程序或简单地更改设计器中的 Text 属性,此代码将不再起作用。但实际上不需要调用,Text 属性 getter 已经自动调用了。

标签: c# multithreading controls compact-framework invoke


【解决方案1】:

与其让其他线程封送回 UI 线程只是为了从控件中读取数据,不如将字符串文本从控件中拉出在线程字符串之前,然后将该字符串提供给新的创建它时的线程。最简单的方法是通过关闭信息的 lambda:

string text = control.Text;
Thread thread = new Thread(() => WriteLog(text));
thread.Start();

然后只需为数据添加一个字符串参数到WriteLog。您可以针对所需的每条信息执行此操作。

除了简单地防止跨线程异常错误之外,此设计的一个关键方面是您现在已将业务逻辑与用户界面分开,这使得应用程序更易于维护。

【讨论】:

    【解决方案2】:

    简单的回答:我认为 .Text 方法应该可以在没有调用的情况下工作。

    你试过了吗?

    [编辑]

    这是一个如何调用的简短示例:

    public class Dlg
    {
       public delegate void UpdateConnLabel(string txt);
       private event UpdateConnLabel _UpdateConnLabel;
    
       public Dlg()
       {
          InitializeComponent();
          _UpdateConnLabel = new UpdateConnLabel(DoUpdateConnectionLabel);
       }
    
       public void UpdateConnectionLabel(String txt)
       {
          this.Invoke(_UpdateConnLabel, new object[] { txt });
       }
    
       private void DoUpdateConnectionLabel(string txt)
       {
          label_connection.Text = txt;
       }
    
    }
    

    您只需在要更新标签上的文本的任何地方调用UpdateConnectionLabel("hello World");

    我希望这有助于理解机制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多