Answered by:
How to delay 3 seconds and do NOT to hang Current Metro Windows?

Question
-
My Scenario is like that:
There is a interface in my WinRT Components ( using C++ ), I do need to query some status each 20ms, and after 3s, Stoping query and return result to Metro windows by callback function, but this operation DO NOT hang Metro windows( using C#).
so How can I implement this function?
Friday, July 20, 2012 6:27 AM
Answers
-
Hello,
I found two way to achieve this,
1. You can use Background task, using the TimeTrigger as trigger. Please follow these document.
http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh977055.aspx
http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.applicationmodel.background.timetrigger.aspx
2. You can use a loop, in every loop you can sleep 20ms and run this loop 150 times.
Best regards,
JesseJesse Jiang [MSFT]
MSDN Community Support | Feedback to us
- Marked as answer by Jesse Jiang Thursday, August 2, 2012 7:22 AM
Monday, July 23, 2012 8:35 AM -
Hi Henador:
In Win8 Metro WinRT Components, it don't allow that syntax like that: _beginthreadex, WatiForSingleObject, e.g.;
and I finally got the right way to implement those requirement:
////////////////////////////////////////
static void OnTimerChanged(ThreadPoolTimer^ DelayTimer);
static TimerElapsedHandler^ g_hTimerElapsed = ref new TimerElapsedHandler(OnTimerChanged);
static ThreadPoolTimer^ g_DelayTimer = nullptr;static void OnTimerChanged(ThreadPoolTimer^ DelayTimer)
{
try
{
//Do your jobs
}
catch( ... )
{
}
}static void ThreadProc( )
{
try
{
TimeSpan delay;
delay.Duration = TIME_REVOLUTION * 10000;//TIME_REVOLUTION is your delay times, unit is second.
g_lpfCallback = lpCallback;
g_lpfProtocol = lpProtocol;if (g_DelayTimer == nullptr )
{
g_DelayTimer = ThreadPoolTimer::CreatePeriodicTimer( g_hTimerElapsed, delay);
}
}
catch( ... )
{
}
}static concurrency::task<void> StartThreadProcTask( )
{
auto workItemHandler = ref new WorkItemHandler([=](IAsyncAction^)
{
try
{
ThreadProc( lpProtocol, lpCallback );
}
catch (...) { }}, CallbackContext::Same);//I don't know what means about "Same" and "Any";
ThreadPool::RunAsync(workItemHandler, WorkItemPriority::Normal, WorkItemOptions::TimeSliced);
return concurrency::task<void>( );
}- Proposed as answer by Jesse Jiang Wednesday, August 1, 2012 9:06 AM
- Marked as answer by Jesse Jiang Thursday, August 2, 2012 7:22 AM
Wednesday, August 1, 2012 7:45 AM
All replies
-
Seems like it would be easier to:
1. Have a C++ component that only does the status query (hardware, I assume?)
2. Use CreatePeriodicTimer in C# and have your C# WorkItem call the C++ component periodically
That way you keep all the timer manipulation and notification stuff in C#.
Friday, July 20, 2012 12:02 PM -
Hello,
I found two way to achieve this,
1. You can use Background task, using the TimeTrigger as trigger. Please follow these document.
http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh977055.aspx
http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.applicationmodel.background.timetrigger.aspx
2. You can use a loop, in every loop you can sleep 20ms and run this loop 150 times.
Best regards,
JesseJesse Jiang [MSFT]
MSDN Community Support | Feedback to us
- Marked as answer by Jesse Jiang Thursday, August 2, 2012 7:22 AM
Monday, July 23, 2012 8:35 AM -
Hi Henador:
I don't think your idea is suitable for my condition, I need to encapsulate this (including timer and query) to WinRT components and privode to metro.
Hi Jesse:
I think the second way is suitable for my condition; but, problem is how to implement a loop in C++ WinRT? As I known, there must be thread. and the point is here is a timer in loop; I found the timer is big different with Win32 API; Oppss, I'm not good at this.
Is that a correct way to create timer?
"DelayTimer =
Windows::System::Threading::
ThreadPoolTimer::CreateTimer
(refnewWindows::System::Threading::TimerElapsedHandler(timerDelegate), delay);"
Monday, July 23, 2012 9:02 AM -
Note that I'm a newbie to WinRT/Metro so I don't know if this will work properly! If you're going to stay in C++ for the whole thing, I would implement the C++ part of Jesse's #2 suggestion like this:
static HANDLE hEventAbort; unsigned int _stdcall QueryThreadProc( void *args ) { for( int i = 0; i < 150; i++ ) { DWORD dwrc; dwrc = WaitForSingleObjectEx( hEventAbort, 20, FALSE ); if( dwrc == WAIT_OBJECT_0 ) { return 1; // aborted } // do query here, notify c# and return if TRUE } // notify c# of timeout return 2; } void StartQueryLoop() { hEventAbort = CreateEventEx( 0, 0, 0, 0 ); _beginthreadex( 0, 0, QueryThreadProc, 0, 0, 0 ); } void AbortQueryLoop() { SetEvent( hEventAbort ); }
I have no idea how to notify a C# app from a thread in a C++ component.
Tuesday, July 24, 2012 2:43 PM -
Hi Henador:
In Win8 Metro WinRT Components, it don't allow that syntax like that: _beginthreadex, WatiForSingleObject, e.g.;
and I finally got the right way to implement those requirement:
////////////////////////////////////////
static void OnTimerChanged(ThreadPoolTimer^ DelayTimer);
static TimerElapsedHandler^ g_hTimerElapsed = ref new TimerElapsedHandler(OnTimerChanged);
static ThreadPoolTimer^ g_DelayTimer = nullptr;static void OnTimerChanged(ThreadPoolTimer^ DelayTimer)
{
try
{
//Do your jobs
}
catch( ... )
{
}
}static void ThreadProc( )
{
try
{
TimeSpan delay;
delay.Duration = TIME_REVOLUTION * 10000;//TIME_REVOLUTION is your delay times, unit is second.
g_lpfCallback = lpCallback;
g_lpfProtocol = lpProtocol;if (g_DelayTimer == nullptr )
{
g_DelayTimer = ThreadPoolTimer::CreatePeriodicTimer( g_hTimerElapsed, delay);
}
}
catch( ... )
{
}
}static concurrency::task<void> StartThreadProcTask( )
{
auto workItemHandler = ref new WorkItemHandler([=](IAsyncAction^)
{
try
{
ThreadProc( lpProtocol, lpCallback );
}
catch (...) { }}, CallbackContext::Same);//I don't know what means about "Same" and "Any";
ThreadPool::RunAsync(workItemHandler, WorkItemPriority::Normal, WorkItemOptions::TimeSliced);
return concurrency::task<void>( );
}- Proposed as answer by Jesse Jiang Wednesday, August 1, 2012 9:06 AM
- Marked as answer by Jesse Jiang Thursday, August 2, 2012 7:22 AM
Wednesday, August 1, 2012 7:45 AM