C#如何在另一个类的线程中对Textbox内容进行修改? 20
public class WinForm: Form
{
public WinServer()
{
InitializeComponent();
}
private void WinServer_Load(object sender, EventArgs e)
{
Receive.Instance.Start();
}
}
还有一个类Receive
public class Receive
{
static Receive_instance = null;
public static Receive Instance
{
get
{
if (null == _instance)
{
_instance = new Receive();
}
return _instance;
}
}
public void Start()
{
try
{
Thread th = new Thread(refresh);
th.IsBackground = true;
th.Start();
}
catch(Exception ex)
{
}
}
void refresh()
{
while (true)
{
//在这里更新TextBox的内容
}
}
}
这个是我的类 ,具体要怎么写? 展开
//recevie类里加几行代码以取得那个textbox
TextBox tb=null;
public void Start(TextBox tb=null)
{
this.tb=tb;
//你原本的start中的其它代码
}
//以下内容也添加至Receive类
public delegate void textbox_delegate(string msg);
public void textbox(string msg)
{
if(tb==null) return;
if(tb.InvokeRequired)
{
textbox_delegate dt = new textbox_delegate(msg);
tb.Invoke(dt, new object[]{msg});
}
else
{
tb.Text=msg;//更新textbox内容
}
}
//refresh就可以为
void refresh()
{
while (true)
{
//在这里更新TextBox的内容
string msg="hello world";
textbox(msg);
Thread.Sleep(0);
}
}
//假定winform中的textbox为txtMsg,那代码就可以写作
Receive.Instance.Start(txtMsg);
textbox_delegate dt = new textbox_delegate(msg);
“msg”是“变量”,但此处被当做“方法”来使用
textbox_delegate dt = new textbox_delegate(textbox);
//自定义一个委托
MyInvokeCapture miCapture = new MyInvokeCapture(UpdatePictureBoxCapture);
if (this.IsHandleCreated)
{
this.BeginInvoke(miDgv, cardId.ToString(), name, swipeDate, controllerName + "[" + controllerSN + "]", (int)status, statusResult, detailInfo);
}
/// <summary>
/// 更新文本框内容 和 刷卡用户登记的照片信息 如果非法闯入 显示为红色
/// </summary>
/// <param name="txt">需要更新的文本框控件</param>
/// <param name="contents">用户的基本信息</param>
/// <param name="pic">需要更新的PictureBox控件</param>
/// <param name="photo">照片</param>
private void UpdateTextBoxAndPicture(RichTextBox txt, string contents, PictureBox pic, object photo, long status)
{
txt.Text = contents;
txt.Select(0, txt.Text.Length);
if (status == 0x84) //非法闯入
{
txt.SelectionColor = Color.Red;
}
else if (status < 4) //正常通过
{
txt.SelectionColor = Color.Black;
}
else //报警通过 显示为蓝色
{
txt.SelectionColor = Color.Blue;
}
if (photo != DBNull.Value)
{
try
{
byte[] buffer = (byte[])photo;
MemoryStream ms = new MemoryStream(buffer);
ms.Read(buffer, 0, buffer.Length);
pic.Image = Image.FromStream(ms);
}
catch
{
pic.Image = null;
}
}
else
{
pic.Image = null;
}
}
你需要知道Control.InvokeRequired的用法。这个与线程操作有关。参考一个代码示例:
在你的WinForm里定义如下的一个函数:
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text;
}
}
在线程里如下调用这个函数:
// This event handler creates a thread that calls a
// Windows Forms control in a thread-safe way.
private void setTextSafeBtn_Click(
object sender,
EventArgs e)
{
this.demoThread =
new Thread(new ThreadStart(this.ThreadProcSafe));
this.demoThread.Start();
}
// This method is executed on the worker thread and makes
// a thread-safe call on the TextBox control.
private void ThreadProcSafe()
{
this.SetText("This text was set safely.");
}
在应用程序中实现多线程的首选方式是使用 BackgroundWorker 组件。 BackgroundWorker 组件使用事件驱动模型实现多线程。 后台线程运行 DoWork 事件处理程序,而创建控件的线程运行 ProgressChanged 和 RunWorkerCompleted 事件处理程序。 可以从 ProgressChanged 和 RunWorkerCompleted 事件处理程序调用控件。
使用 BackgroundWorker 进行线程安全调用
创建一个方法,该方法用于执行您希望在后台线程中完成的工作。 不要调用由此方法中的主线程创建的控件。
创建一个方法,用于在后台工作完成后报告结果。 在此方法中可以调用主线程创建的控件。
将步骤 1 中创建的方法绑定到 BackgroundWorker 的实例的 DoWork 事件,并将步骤 2 中创建的方法绑定到同一实例的 RunWorkerCompleted 事件。
若要启动后台线程,请调用 BackgroundWorker 实例的 RunWorkerAsync 方法。
在下面的代码示例中,DoWork 事件处理程序使用 Sleep 来模拟需要花费一些时间完成的工作。 它不调用窗体的 TextBox 控件。 TextBox 控件的 Text 属性在 RunWorkerCompleted 事件处理程序中直接设置。
// This event handler starts the form's
// BackgroundWorker by calling RunWorkerAsync.
//
// The Text property of the TextBox control is set
// when the BackgroundWorker raises the RunWorkerCompleted
// event.
private void setTextBackgroundWorkerBtn_Click(
object sender,
EventArgs e)
{
this.backgroundWorker1.RunWorkerAsync();
}
// This event handler sets the Text property of the TextBox
// control. It is called on the thread that created the
// TextBox control, so the call is thread-safe.
//
// BackgroundWorker is the preferred way to perform asynchronous
// operations.
private void backgroundWorker1_RunWorkerCompleted(
object sender,
RunWorkerCompletedEventArgs e)
{
this.textBox1.Text =
"This text was set safely by BackgroundWorker.";
}
我就是想问怎么写?
//定义一个委托
private delegate void WriteLogHandle(string format, params object[] parms);
//输出
private void WriteLog(string format, params object[] parms)
{
if (控件名称.InvokeRequired)
{
控件名称.BeginInvoke(new WriteLogHandle(WriteLog), format, parms);
}
else
{
控件名称.AppendText(string.Format(format, parms));
}
}
private object obj = new object();
private void 线程方法(object ps)
{
lock (obj)//加锁
{
WriteLog("aaaa");//给你的控件赋值
}
}