VC6在线程中对进度操作为什么会报错?
VC6在线程中对进度操作为什么会报错?在界面上放一个按钮,当点击按钮时,读取控件的值,后创建一个线程,并把这些值传到线程中,让线程刷新进度条件,从而解放界面的其它操作。
可是在线程中对进度条件的指针操作时程序直接崩溃了。不知道什么原因,各位帮忙看看是什么问题导致的?
声明:
struct TestThreadInfo
{
CProgressCtrl* pctrlProgress;
UINT BeginValue;
UINT EndValue;
UINT StepValue;
UINT StepTime;
int Ctrl;
};
UINT TestThreadFunc(LPVOID lpParam);
按钮消息处理:
void Test::OnButtonTestStart()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
if (Teststate = FALSE)
{
TestThreadPara.pctrlProgress = &m_PrintTestProgress;
TestThreadPara.BeginValue = m_EditBeginFocus;
TestThreadPara.EndValue = m_EditEndFocus;
TestThreadPara.StepTime = m_EditPrintTime;
TestThreadPara.StepValue = m_EditFocusD;
TestThreadPara.Ctrl = TRUE;
Teststate = TRUE;
}
else
Teststate = TRUE;
pThread=AfxBeginThread(TestThreadFunc, &TestThreadPara);
}
线程体:
UINT TestThreadFunc(LPVOID lpParam)
{
TestThreadInfo* pInfo=(TestThreadInfo*)lpParam;
for(int i=0;i<100;i++)
{
int nTemp=pInfo->StepTime;
pInfo->pctrlProgress->SetPos(i);
Sleep(nTemp);
}
return 0;
}
程序运行到pInfo->pctrlProgress->SetPos(i);时直接崩溃了。 http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_666027LX86VS.jpg
(原文件名:未命名.jpg) 进度条之前有没有初始化? 就是设定范围。。。
或者把 线程 函数弄成友员函数 已经初化了
m_StaticTestPercentage = "0%";
m_PrintTestProgress.SetRange(0,99); 我尝试着把线程设成Test类的静态成员也不行 TestThreadInfo之前难道不加 struct 吗??
你的 进度条 应该是 对话框类的吧,直接在
线程函数 里面 用对话框类 指针访问进度条看看
我就是 这么做的。。。
不过我用另外 一个创建线程 的函数,忘记了。。。
你都试试。。 不是struct的问题,将它的声明处改成typedef也不行
我是将进度条控制变量的指针存在结构体里传过去的,
TestThreadPara.pctrlProgress = &m_PrintTestProgress; 你说的线程函数是CreateThread()吧? 跟踪一下,看看pInfo->pctrlProgress句柄对不对 一般不推荐这样访问mfc控件,会产生很多问题,速度过快时尤其。应该用对界面发送消息的形式来控制控件。 这里有10多线程例子,例3跟例5 跟你上面的代码一模一样
点击此处下载 ourdev_666128TZCWPU.rar(文件大小:637K) (原文件名:多线程10例.rar) 搞定了,感谢大家的支持,我有义务把解决方法给写出来,方法是:在线程中给界面发消息,这也是最安全的方法。
1、在把OnButtonTestStart()处创建线程时,把界面的句柄传给线程
2、在线程处理完数据后,发一个消息给界面。
3、在界面中手动增加一个消息处理模块,用于刷新进度条。 回复【10楼】118139
这里有10多线程例子,例3跟例5 跟你上面的代码一模一样
点击此处下载(原文件名:多线程10例.rar)
-----------------------------------------------------------------------
惭愧,你传的这10个例子也是我看了一个高手的教程然后按教程写的,虽然跟着写了遍,但刚才VC遇了问题就蒙了
我的解决办法也正是里面的例7,呵呵,惭愧,惭愧
连接:http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4870136&bbs_page_no=1&search_mode=3&search_text=Onsunsl&bbs_id=9999 晕, 搞电子的朋友们, 软件可复杂啦。
所有界面组件,都是非线程安全的, 也就是说只能有一个线程使用它,你的程序启动后, 主线程在使用它们, 你自己创建的线程, 如果强行访问它们,绝对会报错。
一个程序启动一个进程,一个进程里有一个主线程。
一般来说, 自己创建的线程, 只用来进行数值运算和底层api调用。 如果需要和界面通讯, 绝对不可以直接控制界面组件, 必须通过postmessage 或者sendmessage等方式来传递消息。如果访问主进程里的变量, 可以用锁互斥等技术,但是如果设计巧妙也可以不用,或者对变量仅仅进行读操作!!
尽可能避免创建线程, 如果一定要创建, 尽可能减少创建销毁线程次数, 让一个线程处理数据后, 自动睡眠挂起, 然后有数据了再复活处理数据。。。。 线程的创建开销是很大的。 如果线程太多, 你还得用api对线程的优先级进行处理。。。。 不是struct的问题,将它的声明处改成typedef也不行
我是将进度条控制变量的指针存在结构体里传过去的,
TestThreadPara.pctrlProgress = &m_PrintTestProgress
页:
[1]