从子线程向主线程返回数据出错,高手来,急!

starj1 2008-03-21 07:21:46
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace Test
{
delegate void SetMatchCollectionCallback(System.Text.RegularExpressions.MatchCollection mcT);
public delegate void JobCompleteHandle(System.Text.RegularExpressions.MatchCollection e);
public delegate void BusyStatusChangedHandle(bool e);


public partial class frmMain : Form
{
BGWorker bgwT;

public frmMain()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
dlgOpenFile.ShowDialog();
}

private void dlgOpenFile_FileOk(object sender, CancelEventArgs e)
{
string sT = string.Empty;
using (System.IO.StreamReader srT = new System.IO.StreamReader(dlgOpenFile.FileName, Encoding.Default))
{
sT = srT.ReadToEnd();
}
bgwT = new BGWorker(ref sT, textBox1.Text, System.Text.RegularExpressions.RegexOptions.Multiline);
bgwT.JobComplete += new JobCompleteHandle(bgwT_JobComplete);
bgwT.StartJob();
}

void bgwT_JobComplete(System.Text.RegularExpressions.MatchCollection e)
{
for (Int32 I = 0; I < e.Count; I++)
{
textBox2.AppendText(e[I].Value);//线程间操作无效: 从不是创建控件“textBox2”的线程访问它。
}
}
}

public class BGWorker:System.Windows.Forms.Form//这行不管BGWorker是Form还是Control,结果一样出错。。。
{
public event JobCompleteHandle JobComplete;
private event JobCompleteHandle JobCompletePretreat;

string sToTreat;
string sRegularString;
System.Text.RegularExpressions.RegexOptions roOption;
Control ctrT;

System.Threading.Thread thrT;

public BGWorker(ref string sToTreat, string sRegularString, System.Text.RegularExpressions.RegexOptions roOption)
{
this.sToTreat = sToTreat;
this.sRegularString = sRegularString;
this.roOption = roOption;
ctrT = new Control();
this.JobCompletePretreat += new JobCompleteHandle(BGWorker_JobCompletePretreat);
thrT = new System.Threading.Thread(new System.Threading.ThreadStart(DoJob));
}

//本来在这个事件里想要转到另一个线程去,结果不成功
void BGWorker_JobCompletePretreat(System.Text.RegularExpressions.MatchCollection e)
{
if (ctrT.InvokeRequired)//这个属性总是为false,奇怪!
{
SetMatchCollectionCallback smcT = new SetMatchCollectionCallback(BGWorker_JobCompletePretreat);
this.Invoke(smcT, new object[] { e });
}
else
{
JobComplete(e);
}
}

public void StartJob()
{
thrT.Start();
}

void DoJob()
{
System.Text.RegularExpressions.Regex reT = new System.Text.RegularExpressions.Regex(sRegularString, roOption);
System.Text.RegularExpressions.MatchCollection mcT = reT.Matches(sToTreat);
JobCompletePretreat(mcT);
}
}
}
...全文
234 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
jokeesloat 2011-12-05
  • 打赏
  • 举报
回复
晕 我还以为有结果了,一看只解决了在子线程中一步调用UI数据的问题。
panda3033 2008-03-25
  • 打赏
  • 举报
回复
同样的用invoke
然后在委托里写你调用创建者线程的事件
panda3033 2008-03-25
  • 打赏
  • 举报
回复
回帖是一种美德!传说每天回帖即可获得 10 分可用分!
duping9626 2008-03-22
  • 打赏
  • 举报
回复
要用异步委托处理
zhangqq111 2008-03-22
  • 打赏
  • 举报
回复
textBox2.AppendText(e[I].Value);//线程间操作无效: 从不是创建控件“textBox2”的线程访问它。
上面这句话要用异步调用,也就是委托,因为其它线程 与form线程存在冲突
starj1 2008-03-22
  • 打赏
  • 举报
回复
看了楼上几位的回复,让我有一个结论:
就是说没有办法在上面程序里的BGWorker类里DoJob子线程完成后,就回到类的创建者的线程里再发出JobComplete事件了?
我的目的就是这个啊。
boblaw 2008-03-22
  • 打赏
  • 举报
回复
//首先,在程序中声明一个delegate,并声明一个方法与delegate一致

delegate void AppendText(string text);
private void AppendTextTask(string text)
{
textBox2.AppendText(text);
}


然后将 textBox2.AppendText(e[I].Value);改为如下代码

AppendText d=new AppendText(AppendTextTask);
this.Invoke(d,new object[]{e[I].Value});
yhy0611 2008-03-22
  • 打赏
  • 举报
回复
楼上的都说了,线程间传递消息使用事件

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧