如何在VC ++中获取WPF应用程序的屏幕截图?(How to get screenshot of WPF application in VC++?)
如何在VC ++中获取WPF应用程序的屏幕截图?
在VC ++中,我有一个WPND应用程序窗口的HWND。 使用GDI PrintWindow的传统方法在WPF应用程序上无法正常工作(当WPF渲染速度很慢时会出现黑屏)。 将WPF应用程序的屏幕截图作为HBITMAP的任何其他方法?
How to get screenshot of WPF application in VC++?
In VC++, I have HWND to a window which is WPF application. Traditional method using GDI PrintWindow doesn't work properly on WPF application (get a black screen when the WPF is slow in rendering). Any other method to take screenshot of a WPF application as HBITMAP?
原文:https://stackoverflow.com/questions/7375822
最满意答案
标准没有给出这样的保证,
notify_one
可以唤醒当前正在等待的任何线程(§30.5.1):
void notify_one() noexcept;
效果:如果有任何线程被阻塞等待*this
,则取消阻止其中一个theads。确保特定线程对事件做出反应的唯一方法是唤醒所有线程,然后使用一些额外的同步机制将除了正确的线程之外的所有线程发送回休眠状态。
由于平台必须满足的要求,这是一个基本限制:通常条件变量以等待线程进入挂起状态的方式实现,并且在发生通知之前不会再次由系统调度。 不需要调度程序实现来提供用于选择用于唤醒的特定线程的功能(并且许多实际上没有)。
所以逻辑的这一部分不可避免地必须由用户代码处理,这反过来意味着你必须唤醒所有线程以使其工作,因为这是确保正确的线程将被唤醒的唯一方法。
No such guarantess are given by the standard,
notify_one
may wake any thread that is currently waiting (§30.5.1):
void notify_one() noexcept;
Effects: If any threads are blocked waiting for*this
, unblocks one of those theads.The only way to ensure that a specific thread reacts to the event is to wake all threads and then have some additional synchronization mechanism that sends all but the correct thread back to sleep.
This is a fundamental limitation due to the requirements that the platform has to fulfill: Usually condition variables are implemented in a way that the waiting threads are put into a suspended state and will not get scheduled by the system again until a notify occurs. A scheduler implementation is not required to provide the functionality for selecting a specific thread for waking up (and many actually don't).
So this part of the logic inevitably has to be handled by user code, which in turn means you have to wake up all threads to make it work, because this is the only way to ensure that the correct thread will get woken at all.
相关问答
更多-
线程开始在threads[i] = std::thread(print_id,i); 每个线程将获取互斥锁,然后通过等待条件变量释放它。 这会暂停该线程的执行。 当go()运行时,它会唤醒所有线程,然后它们继续执行。 th.join()调用是在程序退出之前等待每个工作线程完成的主要方法。 请注意,只有设法获取锁定的线程(因此继续等待cv )才会得到通知,其他线程将在稍后获取锁定并看到准备就绪,绕过cv The threads start executing on the line threads[i] = ...
-
boost :: condition_variable - 使用带谓词的wait_for(boost::condition_variable - using wait_for with predicate)[2021-12-08]
建议使用带谓词的wait函数,因为与手写循环相比,它们的出错率较低。 手写循环可能如下所示: for (;;) { if (myPredicate()) { // ... [successful case] break; } else if (myCondition.wait_until(lock, wakeUpTime) == boost::cv_status::timeout) { // ... [timeout case] ... -
有几件事要指出你的代码: 你可能希望在调用shutdown之后加入你的线程,以确保你的主线程在你的其他线程之前没有完成。 m_queue.clear(); 在关机时,在你的m_mtxEvents互斥锁之外完成,这意味着它不像你想象的那样安全。 队列中的'线程安全处理'应该只是关闭一个项目,然后在您处理事件时释放锁。 您没有明确指出,但如果不这样做将导致锁定,从而防止添加项目。 关于像这样的线程阻塞的好消息是,你可以简单地破解和检查其他线程正在做什么,并找到持有该锁的那个线程。 根据我的评论#3,你可能需要很 ...
-
即使在消费者线程中使用unique_lock,生产者线程也有可能首先运行,在消费者调用wait()之前锁定互斥并调用noify(),因此,我的应用程序将缺少第一个nofity()调用。 消费者可以等待或不等待。 如果有什么需要等待的话,那就没有问题了。 如果它没有什么可以等待的,不要叫'等待。 这真的很简单。 如果,并且只有在您想等待时,请等待。 条件变量的存在是为了解决你如何释放锁并等待,而不会冒险等待已经发生的事情的问题。 他们通过提供一个原子释放锁和等待的功能来解决它。 他们不会错过唤醒,因为他们决定 ...
-
标准没有给出这样的保证, notify_one可以唤醒当前正在等待的任何线程(§30.5.1): void notify_one() noexcept; 效果:如果有任何线程被阻塞等待*this ,则取消阻止其中一个theads。 确保特定线程对事件做出反应的唯一方法是唤醒所有线程,然后使用一些额外的同步机制将除了正确的线程之外的所有线程发送回休眠状态。 由于平台必须满足的要求,这是一个基本限制:通常条件变量以等待线程进入挂起状态的方式实现,并且在发生通知之前不会再次由系统调度。 不需要调度程序实现来提供用 ...
-
我做了一些测试,看是否所有的线程在notify_all()调用后都会醒来,即使那些没有计划作为第一个唤醒的线程也会唤醒。 #include
#include #include #include #include std::mutex M; std::condition_variable CV; int var = 0; int main() { std::thread t1{ ... -
将评论转换为答案: condition_variable::wait(lock, pred)等同于while(!pred()) wait(lock); 。 如果pred()返回true则实际上不会发生等待,并且调用立即返回。 您的第一个唤醒来自notify_one()调用; 第二个“唤醒”是因为第二个wait()调用恰好在Stop()调用之后执行,所以你的谓词返回true并且wait()立即返回而不等待。 很明显你在这里得到了(不)幸运:如果第二次wait()调用发生在Stop()调用之前,那么你的工作线程 ...
-
C ++ 11标准没有规定对notify_one和notify_all任何要求; 因此,当您发出condition_variable信号时,不要按住锁定。 但是,信号线程通常需要保持锁定,直到它在唤醒后设置由等待线程检查的条件为止。 如果没有,该程序可能包含比赛。 例如,请参阅此SO问题: 增强同步 。 The C++11 standard does not state any requirement for notify_one and notify_all; so not holding the loc ...
-
使用boost :: condition_variable进行线程同步(Thread syncronization with boost::condition_variable)[2023-11-05]
问题发生在这部分: aux[j]=true; hEvent[j].notify_one(); 第一行表示由hEvent条件变量监视的条件的更改。 第二行宣布对消费者部分的这种改变,即等待该条件变为真。 问题是这两个步骤在没有与消费者同步的情况下发生,这可能导致以下竞争: 消费者检查当前错误的情况。 这发生在受互斥锁m1保护的关键部分。 发生线程切换。 生产者将条件更改为true并通知任何等待的消费者。 线程切换回来。 消费者恢复并呼叫等待。 但是,他已经错过了最后一步发生的通知,所以他将永远等待。 重要的 ... -
发生这种情况是因为当您提供输入( std::cin.get() )并且您没有分离线程或加入它们时,您的程序正在退出。 在Anthony Williams的 Concurrency in Action中 ,声明std::thread::join或std::thread::detach必须在std::thread对象被销毁之前显式调用,否则将调用std::terminate 。 因此,崩溃。 您可以通过让int main等待线程完成执行来修复它: int main() { std::thread t2( ...