请问控件invoke之后无法响应事件怎么办?

风靡义磊 2015-07-12 09:26:18
首先我要做一个progressBar,为此开辟新线程:
            Thread loop = new Thread(new ThreadStart(ThreadProc));
loop.IsBackground = true;
loop.Start();

在新线程的循环中,如果用户按”停止“,就停下来。
      private void ThreadProc()
{

int n = 100000000;
int i;
double sum = 0;
progressBar1.BeginInvoke(new Action(() =>
{
for(i=1;i<n;i++)
{
sum += 1.0 / i;

if(i%1000000==0) progressBar1.Increment(1);

}
MessageBox.Show(sum.ToString());
}));
}

然而一旦invoke了,程序就不再响应用户事件了,请问这该怎么办?

另外还有一个问题,这样异步访问progressBar使得计算用时多了两倍,有什么更好的方法么?
...全文
278 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 7 楼 zhuankeshumo 的回复:
这样http://blog.csdn.net/conmajia/article/details/7831251
值得参考
於黾 2015-07-13
  • 打赏
  • 举报
回复
你先学会用backgroundworker吧 不明白线程是什么,那么就不要直接用线程
风靡义磊 2015-07-13
  • 打赏
  • 举报
回复
引用 10 楼 Z65443344 的回复:
你先学会用backgroundworker吧 不明白线程是什么,那么就不要直接用线程
可以看出,这个例子就是练习用的……正是因为不太懂,所以自己在研究,也百度了不少,可惜没能找到方法。
  • 打赏
  • 举报
回复
“死循环”程序思路是个死穴,如果你不能理解异步设计的想法,会被坑死。
江南小鱼 2015-07-13
  • 打赏
  • 举报
回复
如6#所说,Invoke代码要尽量短小,Invoke的目的是解决跨线程调用UI控件,不要把和UI控件无关的底码放在Invoke里面。
newtee 2015-07-13
  • 打赏
  • 举报
回复
这样http://blog.csdn.net/conmajia/article/details/7831251
Forty2 2015-07-13
  • 打赏
  • 举报
回复
把耗时计算放在Invoke外面就可以了。 Invoke要尽量短,因为它在UI线程上运行,会让UI停止相应。

private void ThreadProc()
{
    int n = 100000000;
    int i;
    double sum = 0;

    for (i = 1; i < n; i++)
    {
        sum += 1.0 / i;
        if (i % 1000000 == 0)
        {
            if (value == 1) break;
            progressBar1.BeginInvoke((Action)delegate
            {
                progressBar1.Increment(1);
            });
        }
    }
    MessageBox.Show(sum.ToString());
}

volatile int value = 0;
private void stopButton_Click(object sender, EventArgs e)
{
    value = 1;
}
1987andy 2015-07-13
  • 打赏
  • 举报
回复
BeginInvoke 要注意上下文
江南小鱼 2015-07-12
  • 打赏
  • 举报
回复
控件的BeginInvoke方法使用的是UI线程,匿名委托代码执行完成之前,UI线程处于阻塞状态,导致按钮事件不响应。 改成this.Invoke方式跨线程访问窗体控件
风靡义磊 2015-07-12
  • 打赏
  • 举报
回复
引用 3 楼 lovelj2012 的回复:
1、你的计算,指的是这堆代码
 for(i=1;i<n;i++)
                        {
                            sum += 1.0 / i;
                        }
                        MessageBox.Show(sum.ToString());
么?你停止按钮单击事件的代码贴出来看看。 2、完成一次计算,指的是从开始执行到MessageBox.Show出值的时间间隔么?
我没贴全,这段代码的for里面还有一句if(value==1) break; value就是初始值为0的全局变量,单击停止就是value=1; 问题不是出在这里,就是invoke以后就所有按钮都不触发点击事件了,视觉上就看得出来。 用时就是for循环耗时啊
江南小鱼 2015-07-12
  • 打赏
  • 举报
回复
1、你的计算,指的是这堆代码
 for(i=1;i<n;i++)
                        {
                            sum += 1.0 / i;
                        }
                        MessageBox.Show(sum.ToString());
么?你停止按钮单击事件的代码贴出来看看。 2、完成一次计算,指的是从开始执行到MessageBox.Show出值的时间间隔么?
风靡义磊 2015-07-12
  • 打赏
  • 举报
回复
引用 1 楼 lovelj2012 的回复:
然而一旦invoke了,程序就不再响应用户事件了,请问这该怎么办?
神马意思?
这样异步访问progressBar使得计算用时多了两倍
你指的是进度条达到100%的耗时?
1.本来假如不Invoke,就是不管progressBar,我可以在计算过程中单击停止按钮,停止计算。 但是加了Invoke之后,点按钮就没反应了。 2.就是完成一次计算的耗时。
江南小鱼 2015-07-12
  • 打赏
  • 举报
回复
然而一旦invoke了,程序就不再响应用户事件了,请问这该怎么办?
神马意思?
这样异步访问progressBar使得计算用时多了两倍
你指的是进度条达到100%的耗时?
因文件超过20M不能上传,所以拆分为两个文件分次上传 第1章 COM背景知识 1.1 COM的起源 1.1.1 软件业面临的挑战 1.1.2 传统解决方案 1.1.3 面向对象程序设计方法 1.1.4 最终解决方案:组件软件 1.1.5 面向对象的组件模型——COM 1.2 COM的发展历程 1.2.1 COM以前的对象技术:DDE、OLE 1、VBX控件 1.2.2 COM首次亮相:OLE2 1.2.3 Microsoft拥抱Internet:ActiveX 1.2.4 更多的新名词:Windows DNA和COM+ 1.2.5 远程对象:ORBs和DCOM 1.2.6 COM的最新版本:COM+ 1.3 COM技术现状 1.3.1 COM与CORBA 1.3.2 COM与Enterprise Java Beans 1.3.3 Windows之外的COM 小结 第2章 从C++到COM 2.1 C++客户重用C++对象——例程DB 2.1.1 C++对象 2.1.2 客户程序 2.2 将C++对象移进DLL中——例程DB_cppdll 2.2.1 成员函数的引出 2.2.2 内存分配 2.2.3 Unicode/ASCII兼容 2.2.4 例程实现 2.2.4.1 修改接口文件 2.2.4.2 修改对象程序 2.2.4.3 修改客户程序 2.3 C++对象使用抽象基类——例程DB_vtbl 2.3.1 问题:私有数据成员被暴露 2.3.2 解决方案:抽象基类 2.3.2.1 什么是抽象基类(Abstract Base Class) 2.3.2.2 实现秘诀:虚函数(Virtual Functions) 2.3.3 使用抽象基类 2.3.4 例程实现 2.3.4.1 修改接口文件 2.3.4.2 修改对象程序 2.3.4.3 修改客户程序 2.4 改由COM库装载C++对象——例程dbalmostcom 2.4.1 COM库 2.4.2 对象创建的标准入口点 2.4.3 标准对象创建API 2.4.4 标准对象注册 2.4.5 例程实现 2.4.5.1 修改接口文件 2.4.5.2 修改对象程序 2.4.5.3 修改客户程序 2.5 将C++对象变成COM对象 2.5.1 引用计数 2.5.2 多接口 2.5.3 IUnknown接口 2.5.4 标准类厂接口:IClassFactory 2.5.5 对象代码的动态卸载 2.5.6 自动注册 2.5.7 例程实现 2.5.7.1 修改接口文件 2.5.7.2 修改对象程序 2.5.7.3 修改客户程序 2.6 为COM对象添加多接口支持 2.6.1 多接口 2.6.2 DEFINE_GUID 2.6.3 例程实现 2.6.3.1 修改接口文件 2.6.3.2 修改对象程序 2.6.3.3 修改客户程序 小结 第3章 COM基础知识 3.1 对象与接口 3.1.1 COM对象 3.1.2 COM接口 3.1.3 IUnknown接口 3.1.3.1 生存期控制:AddRef和Release 3.1.3.2 接口查询:QueryInterface 3.1.4 全球唯一标识符GUID 3.1.5 COM接口定义 3.1.6 接口描述语言IDL 3.2 COM应用模型 3.2.1 客户/服务器模型 3.2.2 进程内组件 3.2.3 进程外组件 3.2.4 COM库 3.2.5 HRESULT返回值 3.2.6 COM与注册表 3.3 COM组件 3.3.1 实现类厂对象 3.3.2 类厂对象的创建 3.3.3 实现自动注册 3.3.4 实现自动卸载 3.4 COM客户 3.4.1 COM对象创建函数 3.4.1.1 CoGetClassObject 3.4.1.2 CoCreateInstance 3.4.1.3 CoCreateInstanceEx 3.4.2 如何调用进程内组件 3.4.3 COM客户调用进程外组件 3.5 进一步认识COM 3.5.1 可重用机制:包容和聚合 3.5.2 进程透明性 3.5.3 安全性机制 小结 第4章 COM扩展技术 4.1 可连接对象机制 4.1.1 客户、接收器与可连接对象 4.1.1.1 接收器 4.1.1.2 可连接对象 4.1.1.3 客户 4.1.2 实现可连接对象 4.1.3 实现接收器 4.1.4 建立接收器与连接点的连接 4.1.5 获得出接口的类型信息 4.2 结构化存储 4.2.1 什么叫结构化存储和复合文件 4.2.2 存储对象和IStorage接口 4.2.2.1 IStorage接口 4.2.2.2 获得IStorage指针 4.2.2.3 释放STATSTG内存 4.2.2.4 枚举存储对象中的元

110,533

社区成员

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

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

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