//主窗口
public partial class frmMain : Form
{
private System.Windows.Forms.TreeView tvChapterSelector;//初始化语句略
OpenStoryFile osfOpenStoryFile = new OpenStoryFile(); public frmMain()
{
InitializeComponent();
} private void frmMain_Load(object sender, EventArgs e)
{
osfOpenStoryFile.OpenStoryFileComplete += new OpenStoryFile.OpenStoryFileCompleteHandle(osfOpenStoryFile_OpenStoryFileComplete);
osfOpenStoryFile.DoOpenStoryFile(@"F:\小说\科幻\回归千年.txt");
} void osfOpenStoryFile_OpenStoryFileComplete(System.Collections.ArrayList e)
{
for (Int32 I = ConstantVars.GlogbalConst.iZero; I < alStoryChapter.Count; I++)
{
tvChapterSelector.Nodes.Add((string)alStoryChapter[I] + string.Empty);//这句报错
//在该控件上执行的操作正从错误的线程调用。使用 Control.Invoke 或 Control.BeginInvoke 封送到正确的线程才能执行此操作。
}
}
} //异步打开文件的类
public class OpenStoryFile
{
public delegate void OpenStoryFileCompleteHandle(System.Collections.ArrayList e); public event OpenStoryFileCompleteHandle OpenStoryFileComplete;
private event OpenStoryFileCompleteHandle OpenStoryFileCompletePretreat; System.Windows.Forms.Control ctrlTurnThread;
System.Threading.Thread thrdOpenFile;
object objForLock = new object(); string StoryFileToOpen; public OpenStoryFile()
{
ctrlTurnThread = new Control();//这里创建控件应该表示这个控件是在主线程创建的吧?
this.OpenStoryFileCompletePretreat += new OpenStoryFileCompleteHandle(OpenStoryFile_OpenStoryFileCompletePretreat);
} void OpenStoryFile_OpenStoryFileCompletePretreat(OpenStoryFile.OpenStoryFileArgs e)
{
if (ctrlTurnThread.InvokeRequired)
{
MessageBox.Show("ctrlTurnThread.InvokeRequired");//但是,这句没有执行到
OpenStoryFileCompleteHandle osfcpT = new OpenStoryFileCompleteHandle(OpenStoryFileCompletePretreat);
ctrlTurnThread.Invoke(osfcpT, new object[] { e });
}
else
{
MessageBox.Show("ctrlTurnThread.InvokeRequired Treated");//直接跑这来了。为什么?
OpenStoryFileComplete(e);
}
} public void DoOpenStoryFile(string StoryFileToOpen)
{
this.StoryFileToOpen = StoryFileToOpen; thrdOpenFile = new System.Threading.Thread(new System.Threading.ThreadStart(OpenStoryFileAsyn));
thrdOpenFile.Start();
} private void OpenStoryFileAsyn()
{
lock (objForLock)
{
if (System.IO.File.Exists(StoryFileToOpen))
{
try
{
System.Collections.ArrayList alStoryChapter = new System.Collections.ArrayList();
//打开文件并作相应处理后,把内容填充到alStoryChapter
}
OpenStoryFileCompletePretreat(alStoryChapter);//调用委托
}
}
}
}
public partial class frmMain : Form
{
private System.Windows.Forms.TreeView tvChapterSelector;//初始化语句略
OpenStoryFile osfOpenStoryFile = new OpenStoryFile(); public frmMain()
{
InitializeComponent();
} private void frmMain_Load(object sender, EventArgs e)
{
osfOpenStoryFile.OpenStoryFileComplete += new OpenStoryFile.OpenStoryFileCompleteHandle(osfOpenStoryFile_OpenStoryFileComplete);
osfOpenStoryFile.DoOpenStoryFile(@"F:\小说\科幻\回归千年.txt");
} void osfOpenStoryFile_OpenStoryFileComplete(System.Collections.ArrayList e)
{
for (Int32 I = ConstantVars.GlogbalConst.iZero; I < alStoryChapter.Count; I++)
{
tvChapterSelector.Nodes.Add((string)alStoryChapter[I] + string.Empty);//这句报错
//在该控件上执行的操作正从错误的线程调用。使用 Control.Invoke 或 Control.BeginInvoke 封送到正确的线程才能执行此操作。
}
}
} //异步打开文件的类
public class OpenStoryFile
{
public delegate void OpenStoryFileCompleteHandle(System.Collections.ArrayList e); public event OpenStoryFileCompleteHandle OpenStoryFileComplete;
private event OpenStoryFileCompleteHandle OpenStoryFileCompletePretreat; System.Windows.Forms.Control ctrlTurnThread;
System.Threading.Thread thrdOpenFile;
object objForLock = new object(); string StoryFileToOpen; public OpenStoryFile()
{
ctrlTurnThread = new Control();//这里创建控件应该表示这个控件是在主线程创建的吧?
this.OpenStoryFileCompletePretreat += new OpenStoryFileCompleteHandle(OpenStoryFile_OpenStoryFileCompletePretreat);
} void OpenStoryFile_OpenStoryFileCompletePretreat(OpenStoryFile.OpenStoryFileArgs e)
{
if (ctrlTurnThread.InvokeRequired)
{
MessageBox.Show("ctrlTurnThread.InvokeRequired");//但是,这句没有执行到
OpenStoryFileCompleteHandle osfcpT = new OpenStoryFileCompleteHandle(OpenStoryFileCompletePretreat);
ctrlTurnThread.Invoke(osfcpT, new object[] { e });
}
else
{
MessageBox.Show("ctrlTurnThread.InvokeRequired Treated");//直接跑这来了。为什么?
OpenStoryFileComplete(e);
}
} public void DoOpenStoryFile(string StoryFileToOpen)
{
this.StoryFileToOpen = StoryFileToOpen; thrdOpenFile = new System.Threading.Thread(new System.Threading.ThreadStart(OpenStoryFileAsyn));
thrdOpenFile.Start();
} private void OpenStoryFileAsyn()
{
lock (objForLock)
{
if (System.IO.File.Exists(StoryFileToOpen))
{
try
{
System.Collections.ArrayList alStoryChapter = new System.Collections.ArrayList();
//打开文件并作相应处理后,把内容填充到alStoryChapter
}
OpenStoryFileCompletePretreat(alStoryChapter);//调用委托
}
}
}
}
先检查控件的句柄(一种Win32窗口句柄)是否已经创建了,你的情况下IsHandleCreated为假,因为该控件还没有初次显示。
如果句柄还没有创建,则尝试检查控件的父控件,而你的情况没有父控件(没有执行过Controls.Add( ctrlTurnThread )之类的语句)。
如果还没有找到,InvokeRequired就直接返回false了。InvokeRequired需要一个窗口句柄来调用API以便知道该窗口所属的线程号,然后比较该线程号和当前线程号,就可以得出需不需要Invoke了。
该API就是GetWindowThreadProcessId()如果你感兴趣的话