我有一个基于 MFC 的大型应用程序,它在主线程中包含一些可能非常慢的任务。这可以使应用程序看起来像是挂起,而实际上它正在完成一项长时间的任务。从可用性的角度来看,我想为用户提供更多有关进度的反馈,并可以选择以干净的方式中止任务。虽然将长期任务分散到单独的线程中将是一个更好的长期解决方案,但我认为实用的短期解决方案是创建一个新的 GUI 线程,封装在它自己的对象中,并带有包含进度条和取消按钮的对话框,用于类似于 CWait 对象的方式。主线程通过 IsCancelled 方法监控取消状态,并在需要时通过抛出结束。
这是一种合理的方法吗?如果是的话,是否已经有一些 MFC 代码可供我使用,或者我应该自己编写?第一张草图看起来像这样
class CProgressThread : public CWinThread
{
public:
CProgressThread(int ProgressMax);
~CProgressThread()
void SetProgress(int Progress);
BOOL IsCancelled();
private:
CProgressDialog *theDialog;
}
void MySlowTask()
{
CProgressThread PT(MaxProgress);
try
{
{
{ // deep in the depths of my slow task
PT.SetProgress(Progress);
if (PT.IsCancelled())
throw new CUserHasHadEnough;
}
}
}
catch (CUserHasHadEnough *pUserHasHadEnough)
{
// Clean-up
}
}
通常,我倾向于使用一个 GUI 线程和多个工作线程,但这种方法可能会为我节省大量的重构和测试工作。有什么严重的潜在陷阱吗?
最佳答案
简短回答,是的您可以在 MFC 中拥有多个 GUI 线程。但是除了创建的线程之外,您不能直接访问 GUI 组件。原因是因为 MFC 下的 Win32 基于每个线程存储 GUI 处理程序。这意味着一个线程中的处理程序对另一个线程不可见。如果您跳转到 CWinThread 类源代码,您可以在那里找到一个处理程序映射属性。
Windows (MFC) 在工作线程和 GUI 线程之间没有明显的区别。任何线程都可以在创建消息队列后更改为 GUI 线程,消息队列是在与消息相关的第一次调用之后创建的,例如 GetMessage()。
在您上面的代码中,如果进度条是在一个线程中创建的,而 MySlowWork() 是在另一个线程中调用的。您只能使用 CProgressThread 属性而不触及 Win32 GUI 相关函数,例如关闭、setText、SetProgress...,因为它们都需要 GUI 处理程序。如果您调用这些函数,错误将是找不到指定的窗口,因为该处理程序不在线程处理程序映射中。
如果您确实需要更改 GUI,则需要将消息发送到该进度条所有者线程。让该线程通过 PostThreadMessage 自行处理消息(消息处理程序),refer to MSDN for detail .
关于c++ - 我可以在 MFC 中有多个 GUI 线程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17340285/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这