2012-09-17 167 views
1

我需要同时计算文本框中元素的总数和元素的数量。所以我决定创建两个线程 - 一个用于数字的长度,另一个用于元素的总和。但是当我只启动一个线程时 - 它的工作是正确的。但是当我开始第二个线程 - 表单开始工作缓慢或停止工作。 创建两个线程在winforms中遇到麻烦

thrd = new Thread(GetLength); 
thrd.Start(); 
thrd1 = new Thread(SetSum); 
thrd1.Start(); 

而这些线程的功能在文本框的数目的计算长度和它的元件的运算量。

private void SetSum() 
{ 
    while (true) 
    { 
     if (this.label3.InvokeRequired) 
      this.Invoke(new Action(() => label3.Text = this.GetSum().ToString())); 
    } 
} 

private int GetSum() 
{ 
    string n = textBox1.Text; 
    int sum = 0; 
    for (int i = 0; i < n.Length; i++) 
    { 
      try 
      { 
       sum += int.Parse(n[i].ToString()); 
      } 
      catch (FormatException) { }; 
     } 
     return sum; 
    } 

private void GetLength() 
{ 
    while (true) 
    { 
      if (this.label2.InvokeRequired) 
       this.Invoke(new Action(() => label2.Text = " | Length = " + textBox1.Text.Length.ToString())); 
    } 
} 

问题在哪里?同步?

我已经找到了解决办法 - 我在while循环对GetLength方法

回答

2

这里有几个问题。

  1. 手头的任务对于(完整)线程来说太小了。线程创建起来很昂贵。
  2. 通过调用主动作,所有工作都在主线程上完成。毕竟,你的解决方案并不是多线程的。
  3. 计数很容易做为Summing的副产品(反之亦然),所以2个线程/任务是矫枉过正的。
  4. while(true) ...循环会拖累你的流程下来,消耗过多的CPU时间白白

这里简单的答案是不使用任何线程,只需要运行一些逻辑textBox1.TextChanged

+0

但除了线程无限循环没有其他解决方案。或者它不会移动到任何其他形式的操作。 – lapots

+2

是的,没有线程。如果目标是在TextBox的内容发生更改时更新标签,则只需TextChanged事件即可。在这种情况下,您的线程方法有太多错误需要修复。 –

+0

TextChanged的解决方案有效! – lapots

1

是,这个问题实际上是在同步增加Thread.Sleep(1):有太多了。

你正在产卵的线程只能做Invoke s,这意味着UI线程正在完成所有工作。

1

您的代码的这部分是一个无任何Thread.Sleep或任何其他等待的无限循环。这将使CPU达到100%。你应该把这个事件或任何其他活动,这将触发GetLength

private void GetLength() 
{ 
    while (true) 
    { 
      if (this.label2.InvokeRequired) 
       this.Invoke(new Action(() => label2.Text = " | Length = " + textBox1.Text.Length.ToString())); 
    } 
} 
+0

我写在文本框中,它计算它的长度 - 我不知道如何改变它(相同的总和) – lapots