How to run a function after a specific time - multithreading

I want to as if there is any way to execute a function after a specific time in windows phone 7.? For instance, see this code in android:
mRunnable=new Runnable()
{
#Override
public void run()
{
// some work done
}
now another function
public void otherfunction()
{
mHandler.postDelayed(mRunnable,15*1000);
}
Now the work done in upper code will be executed after 15 seconds of execution of otherfunction().
And I want to know is this possible in any way in windows phone 7 also.?
Thanx to all in advance..

Although you can use the Reactive Extensions if you want, there's really no need. You can do this with a Timer:
// at class scope
private System.Threading.Timer myTimer = null;
void SomeMethod()
{
// Creates a one-shot timer that will fire after 15 seconds.
// The last parameter (-1 milliseconds) means that the timer won't fire again.
// The Run method will be executed when the timer fires.
myTimer = new Timer(() =>
{
Run();
}, null, TimeSpan.FromSeconds(15), TimeSpan.FromMilliseconds(-1));
}
Note that the Run method is executed on a thread pool thread. If you need to modify the UI, you'll have to use the Dispatcher.
This method is preferred over creating a thread that does nothing but wait. A timer uses very few system resources. Only when the timer fires is a thread created. A sleeping thread, on the other hand, takes up considerably more system resources.

You can do that by using threads:
var thread = new Thread(() =>
{
Thread.Sleep(15 * 1000);
Run();
});
thread.Start();
This way, the Run method wil be executed 15 seconds later.

No need for creating threads. This can be done much more easier using Reactive Extensions (reference Microsoft.Phone.Reactive):
Observable.Timer(TimeSpan.FromSeconds(15)).Subscribe(_=>{
//code to be executed after two seconds
});
Beware that the code will not be executed on the UI thread so you may need to use the Dispatcher.

Related

Groovy calling CountDownLatch.await() lead to hang

I'm new to groovy and have this simple code snippet:
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
CountDownLatch called = new CountDownLatch(1)
Timer timer = new Timer()
timer.schedule(new TimerTask() {
void run() {
called.countDown()
}
}, 0)
assert called.await(2, TimeUnit.SECONDS)
Upon running on command line, it just hang there, nothing happen. I expect that this program should quit at once. So where did I get wrong?
Actually, it's not await that leads to hanging in your case. It's just the Timer's thread is not a daemon. The JVM cannot terminate until all remaining running threads are daemons. As Thread#setDaemon() javadoc states it:
...The Java Virtual Machine exits when the only threads running are all daemon threads.
So in your case
You can just specify that the timer's thread is a daemon
CountDownLatch called = new CountDownLatch(1)
Timer timer = new Timer(true) //true means the underlying thread is a daemon
timer.schedule(new TimerTask() {
void run() {
called.countDown()
}
}, 0)
assert called.await(2, TimeUnit.SECONDS)
println("It's not await that leads to hanging")
Or if for some reason you don't want your timer's thread to be a daemon. E.g. you want the timer to handle all the scheduled tasks before the JVM terminates. In this case you can just cancel the timer at some appropriate moment
CountDownLatch called = new CountDownLatch(1)
Timer timer = new Timer() //now the underlying thread is NOT a daemon
timer.schedule(new TimerTask() {
void run() {
called.countDown()
}
}, 0)
assert called.await(2, TimeUnit.SECONDS)
println("It's not await that leads to hanging")
timer.cancel()//now we are done. All scheduled tasks will be cancelled. However, the running one will finish its job
P.S. If you want more flexible way of scheduling you can take a look at ScheduledThreadPoolExecutor. As Timers javadoc says:
...It is effectively a more versatile replacement for the Timer/TimerTask combination, as it allows multiple service threads, accepts various time units, and doesn't require subclassing TimerTask (just implement Runnable). Configuring ScheduledThreadPoolExecutor with one thread makes it equivalent to Timer.

Windows Azure Worker Role, what to do with the main thread?

So we're setting up a worker role with windows azure and it's running at a very high cpu utilization. I think it has something to do with this section, but I'm not sure what to do about it. Each individual thread that gets started has its own sleep, but the main thread just runs in a while loop. Shouldn't there be a sleep in there or something?
public class WorkerRole : RoleEntryPoint
{
private List<ProcessBase> backgroundProcesses = new List<ProcessBase>();
public override void Run()
{
// This is a sample worker implementation. Replace with your logic.
Trace.WriteLine("BackgroundProcesses entry point called", "Information");
foreach (ProcessBase process in backgroundProcesses)
{
if (process.Active)
{
Task.Factory.StartNew(process.Run, TaskCreationOptions.LongRunning);
}
}
while (true) { }
}
How about something like this, would this be appropriate?
public override void Run()
{
// This is a sample worker implementation. Replace with your logic.
Trace.WriteLine("BackgroundProcesses entry point called", "Information");
List<Task> TaskList = new List<Task>();
foreach (ProcessBase process in backgroundProcesses)
{
if (process.Active)
{
TaskList.Add(Task.Factory.StartNew(process.Run, TaskCreationOptions.LongRunning));
}
}
Task.WaitAll(TaskList.ToArray());
//while (true) { }
}
Your change looks good to me. Sometimes I use Thread.Sleep(Timeout.Infinite).
Have you tested it? Does it reduce the CPU usage? It could be that the tasks themselves actually consume a lot of CPU. We don't know for sure yet that the while loop is the culprit.
The while loop is probably causing your high CPU. It's basically an infinite busy-wait. Your second code sample should work fine, as long as the Tasks you're waiting on never exit. In my personal opinion the best solution is the one outlined in my answer here. If you don't like that, a simpler solution would be to add a Sleep() inside the loop. eg:
while(true){
Thread.Sleep(10000);
}
while loop with empty body will fully load the CPU core to which the thread is dispatched. That's bad idea - you burn CPU time for no good.
A better solution is to insert a Thread.Sleep() with a period ranging anywhere from 100 milliseconds to infinity - it won't matter much.
while( true ) {
Thread.Sleep( /*anything > 100 */ );
}
Once you've got rid of the empty loop body you're unlikely to do any better than that - whatever you do in your loop the thread will be terminated anyway when the instance is stopped.
Just deployed this to production this morning after testing it last night on staging. Seems to be working great. CPU usage went down to .03% average for the background process down from 99.5% ...
public override void Run()
{
// This is a sample worker implementation. Replace with your logic.
Trace.WriteLine("BackgroundProcesses entry point called", "Information");
List<Task> TaskList = new List<Task>();
foreach (ProcessBase process in backgroundProcesses)
{
if (process.Active)
{
TaskList.Add(Task.Factory.StartNew(process.Run, TaskCreationOptions.LongRunning));
}
}
Task.WaitAll(TaskList.ToArray());
//while (true) { }
}

Fire off multiple synchronous threads

I'm not sure if this is a silly question as I don't know much about threads, but is it possible to fire off multiple synchronous threads at the same time, and wait for all to complete before acting? If it is how do you do it?
Certainly the simplest way is to use .NET 4.0 's Task Parallel Library (TPL).
e.g.
Parallel.For(0, 10, x =>
// Do this in Parallel.
System.Diagnostics.Debug.WriteLine(x)
);
see: http://msdn.microsoft.com/en-us/concurrency/bb964701
ut is it possible to fire off multiple synchronous threads at the same time, and wait for all to complete before acting?
"synchronous threads" is an oxymoron, they don't exist.
Of course you can start multiple threads and wait for them to complete (Thread.Join(otherThread))
If it is how do you do it?
Very rarely. Always use as few threads as possible. They are expensive.
Make sure you know about the ThreadPool and (Fx4) the Tasks library, TPL
You can use Parallel.Invoke.
This will execute the supplied actions in parallel and return when all are finished.
You can't really do anything at the same time, let alone fire threads :) (you can fire them rapidly one after the other though, although it is possible that a thread will start before the last one is fired).
As for waiting for them all before continuing, you can use the Join method, which waits for a thread to end before continuing.
Generally you'd do with the construct like below,
public class MultipleThreqadTest
{
private readonly Thread[] threads;
private readonly object locker;
private int finishCounter;
private readonly AutoResetEvent waitEvent;
public MultipleThreqadTest()
{
threads=new Thread[10];
for(int i=0;i<0;i++)
threads[i]=new Thread(DoWork);
finishCounter = threads.Length;
waitEvent=new AutoResetEvent(false);
}
public void StartAll()
{
foreach (var thread in threads)
{
thread.Start();
}
//now wait for all worker threads to complete
waitEvent.WaitOne();
}
private void DoWork()
{
//Do Some Actual work here, you may need to lock this in case you are workin on some shared resource
//lock(locker)
//{
//}
//Check if all worker thread complets
if(Interlocked.Decrement(ref finishCounter)==0)
{
this.waitEvent.Set();
}
}
}

Pause a QThread

UpdateThread is-a QThread That sets up a QTimer in UpdateThread::run() that calls slot UpdateThread::tick() every t ms. Now based upon some condition I need to Pause the Thread and after some time based upon another condition I need to wake it up.
Is the Way I am doing the QTimer thing is Okay ? or I should move the tick code to run and call the QThread::start() every t ms ?
How can I Pause and wake up the threads conditionally
Or I should just stop() the QTimer and start() it latter ?
First of all, you shouldn't define slots on your QThread subclass and call them from within run() - the slots will be executed (by performing a cross-thread slot invocation) in the context of the thread that owns your UpdateThread instance (the same one that created it, unless you called moveToThread() on it), not in the context of the thread represented by UpdateThread. Remember this mnemonic:
In run(), QThread::thread() != this
Instead, define the slots on a QObject subclass that you create inside run().
Ok, with that out of the way, let's have a look at the timer. The QTimer documentation contains the following:
In multithreaded applications, you can use QTimer in any thread that has an event loop.
To start an event loop from a non-GUI thread, use QThread::exec(). Qt uses the timer's
thread affinity to determine which thread will emit the timeout() signal.
Because of this, you must start and stop the timer in its thread; it is not possible to
start a timer from another thread.
(emphasis mine) Take particular note of the last sentence.
The solution is to do a cross-thread call of QTimer::start() and QTimer::stop(). You might know about cross-thread signal/slot connections. This uses the same underlying mechanism, which is exposed in QMetaObject::invokeMethod():
class UpdateThread : public QThread {
Q_OBJECT
private:
QObject * m_timer; // just a QObject* so we're not tempted
// to call functions on it
QMutext m_mutex; // protects 'm_timer'
public:
explicit UpdateThread( QObject * parent=0 )
: QThread( parent ), m_timer( 0 ) {}
// ...
private:
/* reimpl */ void run() {
QTimer timer;
// ...'timer' setup code goes here...
{
const QMutexLocker locker( &m_mutex );
m_timer = &timer; // publish 'timer' through 'm_timer'
}
// main code of run()
exec(); // start event loop so we get timer's timeout()s
// and we can receive cross-thread method calls
{
const QMutexLocker locker( &m_mutex );
m_timer = 0; // un-publish before we delete `timer`
}
}
public Q_SLOTS:
void startTimer() {
const QMutexLocker locker( &m_mutex );
if ( !m_timer ) return;
// perform cross-thread method call:
QMetaObject::invokeMethod( m_timer, "start", Qt::QueuedConnection );
}
void stopTimer() {
const QMutexLocker locker( &m_mutex );
if ( !m_timer ) return;
// perform cross-thread method call:
QMetaObject::invokeMethod( m_timer, "stop", Qt::QueuedConnection );
}
};
Now, this is how you start/stop the timer from the GUI thread. But you were also asking about alternatives.
Move tick() code into run(), call UpdateThread::start() every t milliseconds.
This is suboptimal, as it would create and destroy threads every t ms. Thread creation is still an expensive operation. Also, if UpdateThread::run() isn't done by the time you next call start(), you'll lose timer ticks.
UpdateThread as outlined above.
This isn't too bad, but it's not idiomatic multithreading, I'd say. It's a good solution if the timer fires so often that that alone would slow down the GUI thread somehow, though you might lose timer ticks this way, too.
QThreadPool
My favourite. Move the code that performs tick() into an implementation of QRunnable::run(), and queue a new runnable on a thread pool whenever the timer fires. In this case, the timer would most naturally live in the GUI thread, avoiding the need for cross-thead method calls as outlined above. Unless the GUI thread itself is overloaded, you won't miss any timer ticks. You also get for free scaling to the number of cores in the system (if you don't want that, don't use QThreadPool::globalInstance() but create your own instance and call setMaxThreadCount(1)).

Is there a prefered approach for introducing a delay before a WCF call

As my user changes the CurrentItem of a dataForm, I need to go the server to get addtional data. It's quite likely that the user could scroll through several items before finding the desired one. I would like to sleep for 500ms before going to get the data.
Is there a component already in the SDK or toolkit like a background worker that would assist in getting back to the UI thread to make my WCF async call once the 500ms sleep is done? It seems that if I don't do that, and try instead to call the WCF async method on the sleeper thread then the Completed event fires on the sleeper thread and not the UI thread, which of course is not good.
I think you might be a little off-track in your thinking. I'm not sure why you feel you need to get back to the UI thread in order to make the asych call. Generally you do as much work as you can on a BG thread and only marshal back to the UI thread when you have the results (by way of the Dispatcher).
I typically use a System.Threading.Timer for this purpose:
public class MyViewModel
{
private readonly Timer refreshTimer;
public MyViewModel()
{
this.refreshTimer = new Timer(this.DoRefresh);
}
public object CurrentItem
{
get { ... }
set
{
...
Invalidate();
}
}
// anything that should invalidate the data should wind up calling this, such as when the user selects a different item
private void Invalidate()
{
// 1 second delay
this.refreshTimer.Change(1000, Timeout.Infinite);
}
private void DoRefresh()
{
// make the async call here, with a callback of DoRefreshComplete
}
private void DoRefreshComplete()
{
// update the UI here by way of the Dispatcher
}
}

Resources