using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading;namespace KeyPressTwice { /// <summary> /// 由于子线程不能修改UI界面上空间信息, /// To remedy this, you will have to use a dispatcher as descibed in the MSDN article: /// <a pref="http://msdn.microsoft.com/en-us/library/ms171728.aspx">How to: Make Thread-Safe Calls to Windows Forms Controls</a> /// </summary> public partial class Form1 : Form { private bool canRun = false; private Thread thread; delegate void SetTextCallback(string text); public Form1() { InitializeComponent(); thread = new Thread(ShowCounter); } public void ShowCounter() { int counter = 0; while (true) { SetText((counter++).ToString()); Thread.Sleep(1000); } } private void SetText(string text) { if (this.textBox1.InvokeRequired) { SetTextCallback backCall = new SetTextCallback(SetText); this.Invoke(backCall, new Object[] { text }); } else { this.textBox1.Text = text; } } private void textBox1_KeyPress(object sender, KeyPressEventArgs e) { switch(Char.ToLower(e.KeyChar)) { case 's': if (thread.ThreadState == ThreadState.Unstarted) { thread.Start(); } else if (thread.ThreadState == ThreadState.Aborted) { thread = new Thread(ShowCounter); thread.Start(); } break; case 'f': e.Handled = true; thread.Abort(); break; default: break; }
} private void justCycle() { int i = 0; while (true) { textBox1.Text = Convert.ToString(i++); if (canRun) { break; } } } } } 希望解决了你的问题
如果,只需要在某些Form中消除Cross-thread InvalidOperationException建议,可以在Form.cs在代码初始化中,将Control.CheckForIllegalCrossThreadCalls = false; 可以完成using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading;namespace KeyPressTwice { /// <summary> /// 由于子线程不能修改UI界面上空间信息, /// To remedy this, you will have to use a dispatcher as descibed in the MSDN article: /// <a pref="http://msdn.microsoft.com/en-us/library/ms171728.aspx">How to: Make Thread-Safe Calls to Windows Forms Controls</a> /// </summary> public partial class Form1 : Form { private bool canRun = false; private Thread thread; delegate void SetTextCallback(string text); public Form1() { InitializeComponent(); thread = new Thread(ShowCounter); Control.CheckForIllegalCrossThreadCalls = false; } public void ShowCounter() { int counter = 0; while (true) { SetText((counter++).ToString()); Thread.Sleep(1000); } } private void SetText(string text) { //if (this.textBox1.InvokeRequired) //{ // SetTextCallback backCall = new SetTextCallback(SetText); // this.Invoke(backCall, new Object[] { text }); //} //else { this.textBox1.Text = text; } } private void textBox1_KeyPress(object sender, KeyPressEventArgs e) { switch(Char.ToLower(e.KeyChar)) { case 's': if (thread.ThreadState == ThreadState.Unstarted) { thread.Start(); } else if (thread.ThreadState == ThreadState.Aborted) { thread = new Thread(ShowCounter); thread.Start(); } break; case 'f': e.Handled = true; thread.Abort(); break; default: break; }
比如有一个 textbox1 控件,当按下回车 时,触发它的 KeyPress 事件,开始执行一个循环,当再次按下键盘的任意键时,结束这个循环。试了很多办法都不行,现在需要解决的问题就是怎样在循环体内检查键盘是否有按下?
bool _a=true;
线程 _thread=null;
点击事件(...)
{
if(thread==null)
{
thread=.....(匿名方法);
}
if(a)
{
thread.start();
}
else
{
thread.sleep();
}
a=!a;
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;namespace KeyPressTwice
{
/// <summary>
/// 由于子线程不能修改UI界面上空间信息,
/// To remedy this, you will have to use a dispatcher as descibed in the MSDN article:
/// <a pref="http://msdn.microsoft.com/en-us/library/ms171728.aspx">How to: Make Thread-Safe Calls to Windows Forms Controls</a>
/// </summary>
public partial class Form1 : Form
{
private bool canRun = false;
private Thread thread;
delegate void SetTextCallback(string text);
public Form1()
{
InitializeComponent();
thread = new Thread(ShowCounter);
} public void ShowCounter()
{
int counter = 0;
while (true)
{
SetText((counter++).ToString());
Thread.Sleep(1000);
}
} private void SetText(string text)
{
if (this.textBox1.InvokeRequired)
{
SetTextCallback backCall = new SetTextCallback(SetText);
this.Invoke(backCall, new Object[] { text });
}
else
{
this.textBox1.Text = text;
}
} private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
switch(Char.ToLower(e.KeyChar))
{
case 's':
if (thread.ThreadState == ThreadState.Unstarted)
{
thread.Start();
}
else if (thread.ThreadState == ThreadState.Aborted)
{
thread = new Thread(ShowCounter);
thread.Start();
}
break;
case 'f':
e.Handled = true;
thread.Abort();
break;
default:
break;
}
} private void justCycle()
{
int i = 0;
while (true)
{
textBox1.Text = Convert.ToString(i++);
if (canRun)
{
break;
}
}
}
}
}
希望解决了你的问题
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;namespace KeyPressTwice
{
/// <summary>
/// 由于子线程不能修改UI界面上空间信息,
/// To remedy this, you will have to use a dispatcher as descibed in the MSDN article:
/// <a pref="http://msdn.microsoft.com/en-us/library/ms171728.aspx">How to: Make Thread-Safe Calls to Windows Forms Controls</a>
/// </summary>
public partial class Form1 : Form
{
private bool canRun = false;
private Thread thread;
delegate void SetTextCallback(string text);
public Form1()
{
InitializeComponent();
thread = new Thread(ShowCounter);
Control.CheckForIllegalCrossThreadCalls = false;
} public void ShowCounter()
{
int counter = 0;
while (true)
{
SetText((counter++).ToString());
Thread.Sleep(1000);
}
} private void SetText(string text)
{
//if (this.textBox1.InvokeRequired)
//{
// SetTextCallback backCall = new SetTextCallback(SetText);
// this.Invoke(backCall, new Object[] { text });
//}
//else
{
this.textBox1.Text = text;
}
} private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
switch(Char.ToLower(e.KeyChar))
{
case 's':
if (thread.ThreadState == ThreadState.Unstarted)
{
thread.Start();
}
else if (thread.ThreadState == ThreadState.Aborted)
{
thread = new Thread(ShowCounter);
thread.Start();
}
break;
case 'f':
e.Handled = true;
thread.Abort();
break;
default:
break;
}
} }
}