Windows Service and timers - multithreading

I am learning creating windows services and threading. I am using a library provided by fellow worker that aids in building threaded service but this is not giving me the knowledge at the basic level.
Lets say i will have a service that will be long running (little advance than the basic example available on the net), needs to wake up every 15 seconds and then perform its action (basically will be always running). Action involves looking for a status in the DB and then performing actions.
How should the following be handled in such cases:
1. disposing the thread
2. in cases where action takes longer to execute than the interval.
I have found the following example but i am having problems with the above 2 points. Please do keep in mind that the service will be running always.
http://www.java2s.com/Tutorial/CSharp/0280__Development/CreatethedelegatethattheTimerwillcall.htm
using System;
using System.Threading;
class MainClass
{
public static void CheckTime(Object state)
{
Console.WriteLine(DateTime.Now);
}
public static void Main()
{
TimerCallback tc = new TimerCallback(CheckTime);
Timer t = new Timer(tc, null, 1000, 500);
Console.WriteLine("Press Enter to exit");
int i = Console.Read();
// clean up the resources
t.Dispose();
t = null;
}
}
So in my example, what will go in
1. stop event
2. Does start event looks good?
3. what should happen if nothing found in the queue?
4. What if the actions take longer than the interval?
public partial class QueueService : ServiceBase
{
public QueueService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
TimerCallback tc = new TimerCallback(CheckQueue);
Timer t = new Timer(tc, null, 10000, 15000); //first time wait for 10seconds and then execte every 15seconds
}
catch (Exception ex)
{
what should i be checking here and then also make sure that the threading/timer doesn't stop. It should still execute every 15 seconds
}
}
protected override void OnStop()
{
what needs to go here...
}
private static void CheckQueue(Object state)
{
... Connect to the DB
... Check status
... if queue status found then perform actions
. A
. C
. T
. I
. O
. N
. S
... if end
}
}
Thanks for looking!

Disposing the timer.
Not completely. You need to declare the timer at class level otherwise it will be collected after few iterations.
Nothing.
Stop the timer before you check the queue and start it again after you finish with it. This way you won't get into troubles of shared memory or other collisions.
public partial class QueueService : ServiceBase
{
Timer timer;
public QueueService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
TimerCallback tc = new TimerCallback(CheckQueue);
timer = new Timer(tc, null, 10000, 15000);
}
catch (Exception ex)
{
}
}
protected override void OnStop()
{
if (timer != null)
timer.Dispose();
}
private static void CheckQueue(Object state)
{
timer.Change(Timeout.Infinite, 0);
... Connect to the DB
... Check status
... if queue status found then perform actions
. A
. C
. T
. I
. O
. N
. S
... if end
timer.Change(10000, 15000);
}
}

Related

How do I replace Asynctask with RxJava Observer?

I have a test project with Room database. Using Asynctask I can successfully insert an object with some test data into the database. I'm trying to learn RxJava and replace Asynctask with RxJava's observer, but it doesn't work. I have read alot of documentation and watched tutorials, but I don't think I quite get it. Here's the relevant code:
Here I set my Room object with the data from my List:
for(ObjectForArray item: listToDatabase) {
myRoomEntity.setName( item.getName() );
Log.d( "TAG", myRoomEntity.getName() );
}
Then I try to use RxJava Observable to insert data into the database. This was originally and successfully done using Asynctask:
Observable<MyRoomEntity> myRX = Observable
.just(myRoomEntity)
.subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() );
myRX.subscribe( new Observer<MyRoomEntity>() {
#Override
public void onSubscribe(Disposable d) {
Log.d("TAG ONSUBSCRIBE", d.toString());
try {
myViewModel.insertDatabase( myRoomEntity );
Log.d( "TAG", "Populating database Success" );
}catch(Error error) {
Log.d( "TAG", error.toString() );
}
}
The OnNext, OnError and OnComplete are empty.
When I run the project it crashes with the error:
Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
I'm obviously using RxJava wrong since the point is to do asynchronous tasks away from the main thread.
i have use RX java in replace of Asyntask as it has been deprecated in android 9
there are multiple replacements that android provides like Executors, threads, Listenable Futures , Coroutines 🔥, so you are looking how to implement this with rxjava and how RX Java java helps your to migrate just add these dependencies first in gradle
implementation "io.reactivex.rxjava2:rxjava:2.2.20"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
once you import lets start working with RX java i will let you know where you can put background task, pre execute, on post execute like asynctask
lets start codding with Rx java first , i have comment in the method that will help you to put the code
Observable.fromCallable(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
/// here is your background task
return true;
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Boolean>() {
#Override
public void onSubscribe(Disposable d) {
//// pre execute here is my progress dialog
showProgressDialog(getString(R.string.scanning));
}
#Override
public void onNext(Boolean aBoolean) {
//// here is on sucess you can do anystuff here like
if (aBoolean){
/// if its value true you can go ahead with this
}
}
#Override
public void onError(Throwable e) {
/// this helps you to go if there is any error show dialog whatever you wants here
Log.e("error of kind",e.getMessage() );
}
#Override
public void onComplete() {
/// when your task done means post execute
}
});
once its done lets start working with implementation
Observable.fromCallable(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
/// here is your background task
uribitmap = getScannedBitmap(original, points);
uri = Utils.getUri(getActivity(), uribitmap);
scanner.onScanFinish(uri);
return true;
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Boolean>() {
#Override
public void onSubscribe(Disposable d) {
//// pre execute here is my progress dialog
showProgressDialog(getString(R.string.scanning));
}
#Override
public void onNext(Boolean aBoolean) {
//// here is on sucess you can do anystuff here like
if (aBoolean){
/// if its value true you can go ahead with this
}
}
#Override
public void onError(Throwable e) {
/// this helps you to go if there is any error show dialog whatever you wants here
Log.e("error of kind",e.getMessage() );
}
#Override
public void onComplete() {
/// when your task done means post execute
uribitmap.recycle();
dismissDialog();
}
});
now i will do this with executors :
/// pre execute you can trigger to progress dialog
showProgressDialog(getString(R.string.scanning));
ExecutorService executors = Executors.newSingleThreadExecutor();
executors.execute(new Runnable() {
#Override
public void run() {
//// do background heavy task here
final Bitmap uribitmap = getScannedBitmap(original, points);
uri = Utils.getUri(getActivity(), uribitmap);
scanner.onScanFinish(uri);
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
//// Ui thread work like
uribitmap.recycle();
dismissDialog();
}
});
}
});
You are getting this error because you are trying to insert an Object on the main (UI) thread.
You should do something like this:
Observable.fromCallable(() -> myViewModel.insertDatabase( myRoomEntity ))
.subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() );
And then use an Observer to subscribe to the Observable.
Please try restructuring your code like this:
Completable.fromAction(() -> myViewModel.insertDatabase(myRoomEntity))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(() -> Log.d("TAG", "Populating database Success"),
throwable -> Log.d("TAG", throwable.toString()))
Considerations:
If your myRoomEntity is not available before this whole construct gets subscribed, make sure you use defer http://reactivex.io/documentation/operators/defer.html
Your subscribe section handlers are operating on "main", that's why you were receiving a crash.
If possible, avoid unnecessary just calls

Java: Running transaction in multithreaded environment

We are launching a website that will have a very heavy volume for a short period of time. It is basically giving tickets. The code is written in Java, Spring & Hibernate. I want to mimic the high volume by spawning multiple threads and trying to get the ticket using JUnit test case. The problem is that in my DAO class the code just simply dies after I begin transaction. I mean there is no error trace in the log file or anything like that. Let me give some idea about the way my code is.
DAO code:
#Repository("customerTicketDAO")
public class CustomerTicketDAO extends BaseDAOImpl {// BaseDAOImpl extends HibernateDaoSupport
public void saveCustomerTicketUsingJDBC(String customerId) {
try{
getSession().getTransaction().begin(); //NOTHING HAPPENS AFTER THIS LINE OF CODE
// A select query
Query query1 = getSession().createSQLQuery("my query omitted on purpose");
.
.
// An update query
Query query2 = getSession().createSQLQuery("my query omitted on purpose");
getSession().getTransaction().commite();
} catch (Exception e) {
}
}
Runnable code:
public class InsertCustomerTicketRunnable implements Runnable {
#Autowired
private CustomerTicketDAO customerTicketDAO;
public InsertCustomerTicketRunnable(String customerId) {
this.customerId = customerId;
}
#Override
public void run() {
if (customerTicketDAO != null) {
customerTicketDAO.saveCustomerTicketUsingJDBC(customerId);
}
}
}
JUnit method:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations={"file:src/test/resources/applicationContext-test.xml"})
public class DatabaseTest {
#Before
public void init() {
sessionFactory = (SessionFactory)applicationContext.getBean("sessionFactory");
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
customerTicketDAO = (CustomerTicketDAO)applicationContext.getBean("customerTicketDAO");
}
#After
public void end() throws Exception {
SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
SessionFactoryUtils.closeSession(session);
}
#Test
public void saveCustomerTicketInMultipleThreads () throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
for (int i=0; i<1000; i++) {
executor.submit(new InsertCustomerTicketRunnable(i));
}
// This will make the executor accept no new threads
// and finish all existing threads in the queue
executor.shutdown();
// Wait until all threads are finish
executor.awaitTermination(1, TimeUnit.SECONDS);
}
I see no data being inserted into the database. Can someone please point me as to where I am going wrong?
Thanks
Raj
SessionFactory is thread safe but Session is not. So my guess is that you need to call SessionFactoryUtils.getSession() from within each thread, so that each thread gets its own instance. You are currently calling it from the main thread, so all children threads try to share the same instance.
Naughty, naughty!
public void saveCustomerTicketUsingJDBC(String customerId) {
try {
getSession().getTransaction().begin(); //NOTHING HAPPENS AFTER THIS LINE OF CODE
.
.
} catch (Exception e) {
}
}
You should never (well, hardly ever) have an empty catch block, if there is a problem you will find that your code 'just simply dies' with no log messages. Oh look, that's what's happening ;)
At the very minimum you should log the exception, that will go a long way towards you helping you find what the problem is (and from there, the solution).

Android: "Application level" Pause and Resume [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I've been trying to get Application Level Pause and Resume similar to an activity's onPause and onResume. I know there's no API that has this functionality.
I try to follow this post: http://curioustechizen.blogspot.com/2012/12/android-application-level-pause-and.html
But I've had no luck so far.
Has anyone been able to achieve this? What paradigm did you use?
Let me know if you need me to paste some code into this question.
Thanks for the help
Another solution to the problem would be to just keep track of the count of onStart() and onStop() calls from every activity. Example:
First, create a class to hold the counts:
public class ActiveActivitiesTracker {
private static int sActiveActivities = 0;
public static void activityStarted()
{
if( sActiveActivities == 0 )
{
// TODO: Here is presumably "application level" resume
}
sActiveActivities++;
}
public static void activityStopped()
{
sActiveActivities--;
if( sActiveActivities == 0 )
{
// TODO: Here is presumably "application level" pause
}
}
}
Then in every activity, simply call the activityStarted() and activityStopped() methods:
#Override
public void onStart() {
super.onStart();
ActiveActivitiesTracker.activityStarted();
}
#Override
public void onStop() {
super.onStop();
ActiveActivitiesTracker.activityStopped();
}
I had the same problem. My aim was to lock the App, if the user abandons it. A simple aim, which i thought would be easy to implement. But all the solutions I found were way to complex. So I came to a simple solution: A time based lock.
Basically it works like this:
Start countdown to lock app in onPause
Stop countdown in onResume
If onResume is not called in time, change to locked
Therefor I created a small little class:
public class ApplicationLock {
private static final String TAG = ApplicationLock.class.getSimpleName();
private static final int LOCK_TIME = 1000; //lock after a second
private static boolean lock = true; //default is locked
private static Handler handler = new Handler();
private static Runnable runnable = new Runnable() {
#Override
public void run() {
lock = true;
Log.i("ActivityTracker", "App locked");
}
};
public static boolean activityStarted()
{
handler.removeCallbacks(runnable);
if(lock)
{
Log.i(TAG, "App resumed - LOCKED");
return true;
}else{
Log.i(TAG, "App resumed - NOT LOCKED");
return false;
}
}
public static void activityStopped()
{
handler.postDelayed(runnable, LOCK_TIME);
Log.i(TAG, "App paused - Starting countdown");
}
Just call activityStopped() in your activities onPause() and activityStarted() in onResume(). Check the result of activityStarted(). If it returns true, lock your app. If the orientation of the app is changed, onResume will be called very quickly after onPause, so the app will not lock.
This solution might not fit every scenario, but in my case it was the best solution. Additionally you can change the countdown, to increase the user experience (The user pressed a wrong button and returns to the app in a few seconds, no need to lock the app). Hope this is useful to someone else.
I have done something very similar to this in an app which used a service that provided GPS functions by several activities. The idea was to only have the service there when one of the activities that used it is visible, and not there when none are visible. In your case, every activity would hook into a service, and you will know when the entire application was paused or resumed by hooking into the service's onCreate() and onDestroy() methods.
Here is a stripped-down example:
Components needed (these could probably be placed into a utility class if you want to reuse them, or I just had them for each activity class):
private boolean mAppActiveServiceBound = false;
private AppActiveService mAppActiveService = null;
private ServiceConnection mAppActiveConnection = new ServiceConnection() {
public void onServiceConnected( ComponentName className, IBinder service ) {
mAppActiveService = ( (AppActiveService.AppActiveBinder) service ).getService();
}
public void onServiceDisconnected( ComponentName className ) {
mAppActiveService = null;
}
};
Then in your onStart() and onStop() methods for each activity:
#Override
public void onStart() {
super.onStart();
mAppActiveServiceBound = bindService( new Intent( this, AppActiveService.class ), mAppActiveConnection, Context.BIND_AUTO_CREATE );
}
#Override
public void onStop() {
super.onStop();
if( mAppActiveServiceBound ) {
unbindService( mAppActiveConnection );
mAppActiveServiceBound = false;
}
}
And finally, the service itself:
public class AppActiveService extends Service {
// Receives interactions from clients:
private final IBinder mBinder = new AppActiveBinder();
/**
* Provides a handle to the bound service.
*/
public class AppActiveBinder extends Binder {
AppActiveService getService() {
return AppActiveService.this;
}
}
#Override
public void onCreate(){
// TODO: Here is presumably "application level" resume
}
#Override
public void onDestroy(){
// TODO: Here is presumably "application level" pause
}
}

Seeking C# threading clarification

I'm new to threading; in fact I'm not even trying to multi- thread the Windows Forms app I'm working on, but all of my searches on this issue lead me to the topic of multithreading. When debugging in Visual Studio 2010 Express, it seems to "jump around" to use the term I've seen others use to describe the same problem. When I let it run, sometimes it runs as expected, other times it just seems to keep running, getting hung up.
In trying to hone my question, I think I need to figure out:
If the timer class calls a method on a different thread, and there isn't an obvious danger of unpredictable instance values/ state corruption in the executing code (there aren't any conditional checks of instance variables etc), why would that method called by the timer appear to behave unpredictably? To me it seems that the code should run synchronously, and if a different thread is used for part of the process, so be it. I can't see where there is opportunity for thread corruption.
When the program starts, it prompts for the timer to be set to run a data download process. After the procedure runs, the timer is set again to a default time, at the end of the procedure. Consistently, the initial timer setting works, and fires as expected, running the data download process... it's that data download method, somewhere within it it goes awry. The last line of code is what sets the timer again, but I can't tell if it's getting hit while debugging it. (jumping around)..
I've added relevant code below... and I stepped into every procedure in my code from the beginning... they all show current thread id 10. This is up to an including the timer firing off, and stopping at a breakpoint at the very next line to execute, which is the data download process. The current thread at that point: 14. I've built the solution before running it/ trying to debug btw. Any ideas?
public partial class frmTradingAppMain : Form
{
private TradingAppDataRunManager drm;
private void frmTradingAppMain_Shown(object sender, EventArgs e)
{
drm = new TradingAppDataRunManager();
drm.StatusChanged += new DataRunManager.DRMStatusChangeHandler(UpdateFormData);
drm.InitializeOrScheduleDataRun();
}
private void UpdateFormData()
{
this.Invoke(new DataRunManager.DRMStatusChangeHandler(UpdateFormDataImpl));
}
private void UpdateFormDataImpl()
{
lblDataDwnLoadManagerStatus.Text = Convert.ToString(drm.Status);
if (drm.Status == DataRunManager.DRMStatus.Inactive)
{
lblNextScheduledDataDownloadDate.Text = "Date not set.";
lblNextScheduledDataDownloadTime.Text = "Time not set.";
}
else
{
lblNextScheduledDataDownloadDate.Text = drm.DateTimeOfNextScheduledDataRun.ToShortDateString();
lblNextScheduledDataDownloadTime.Text = drm.DateTimeOfNextScheduledDataRun.ToShortTimeString();
}
}
}
public abstract class DataRunManager
{
protected DataRunTimer dataRuntimer;
public delegate void DRMStatusChangeHandler();
public event DRMStatusChangeHandler StatusChanged;
public DRMStatusChangeHandler statusChanged;
public void InitializeOrScheduleDataRun()
{
if (DataRunIsAvailable() && UserWouldLikeToPerformDataRun())
RunMainDataProcedure(null);
else
ScheduleDataRun();
}
public void RunMainDataProcedure(object state)
{
start = DateTime.Now;
Status = DRMStatus.Running;
StatusChanged();
GetDataCollections();
foreach (DataCollection dcl in dataCollectionList)
{
dcl.RunDataCollection();
dcl.WriteCollectionToDatabase();
}
PerformDBServerSideProcs();
stop = DateTime.Now;
WriteDataRunStartStopTimesToDB(start, stop);
SetDataRunTimer(DateTimeOfNextAvailableDR());
}
public void ScheduleDataRun()
{
FrmSetTimer frmSetTimer = new FrmSetTimer(DateTimeOfNextAvailableDataRun);
DateTime currentScheduledTimeOfNextDataRun = DateTimeOfNextScheduledDataRun;
DRMStatus currentStatus= Status;
try
{
frmSetTimer.ShowDialog();
DateTimeOfNextScheduledDataRun = (DateTime)frmSetTimer.Tag;
SetDataRunTimer(DateTimeOfNextScheduledDataRun);
}
catch
{
Status = currentStatus;
DateTimeOfNextScheduledDataRun = currentScheduledTimeOfNextDataRun;
}
}
}
public class DataRunTimer
{
System.Threading.Timer timer;
public DataRunTimer(){}
public void SetNextDataRunTime(TimerCallback timerCallback, DateTime timeToSet)
{
if (timer == null)
timer = new System.Threading.Timer(timerCallback);
TimeSpan delayTime = new TimeSpan(timeToSet.Day - DateTime.Now.Day, timeToSet.Hour - DateTime.Now.Hour, timeToSet.Minute - DateTime.Now.Minute,
timeToSet.Second - DateTime.Now.Second);
TimeSpan intervalTime = new TimeSpan(0, 0, 10);
timer.Change(delayTime, intervalTime);
}
public void DataRunTimerCancel()
{
if (timer != null)
timer.Dispose();
}
}

Working with threads in blackberry

I am using threads in blackberry to perform web service calls. I want to get notified as soon as the call gets a response back. I was using
Handlers
in android. I didnt find anything similar in blackberry.
Here is the code I am using to run the thread
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
How can I get a notification after the thread finished running?
How can I do this in blackberry?
Thanks
Added more Information : Thanks for your reply. Its really
informative. Let me explain a bit more on my issue. I have a
webservice call which is running on a thread. As soon as I get the
reply back from server I want to execute the next function(next call
to server) which is based on the response from the previous call.So I need to wait until I get a response back. Also
at them same time I need to show a activity indicator on screen. I was
using handler for this in android. I am looking for something similar
on blackberry.
So your question essentially is this
One thread does the job while the other thread waits for completion
The first thread completes the job and "notifies" the second thread.
This is a simple producer consumer problem. Here is the code how you can solve this.
class JobResult
{
boolean done = false;
}
JobResult result = new JobResult();
class Worker extends Thread
{
JobResult _result;
public Worker( JobResult result )
{
_result = result
}
public void run()
{
// Do some very long job
synchronized( _result )
{
// modify result
_result.done = true;
_result.notify();
}
}
}
public class Waiter extends Thread
{
JobResult _result;
public Waiter( JobResult result )
{
_result = result;
}
public void run()
{
synchroinzed( _result ){
while(! _result.done)
{
this.wait();
}
}
// Wait is over. You can do something now.
}
}
As I got the Zach's question - he asks how to execute some code that involves UI changes (something like showing an info popup or closing the progress popup) upon a background thread completion. On Android a Handler created on the UI thread is often used for that purpose.
In BB you can use another way which is similar to Swing on desktop Java. When you need some code to be executed on the UI thread you wrap it in a Runnable and pass to one of the following methods:
// Puts runnable object into this application's event queue,
// and waits until it is processed.
Application.invokeAndWait(Runnable runnable)
// Puts runnable object into this application's event queue.
Application.invokeLater(Runnable runnable)
// Puts runnable object into this application's event queue
// for repeated execution.
Application.invokeLater(Runnable runnable, long time, boolean repeat)
So the behaviour of the above calls is similar to what Handler.post(Runnable r) (and the like) does.
Note, you can always get a handle to your Application instance by a static call Application.getApplication().
So in the end of a background thread it is safe to do something like this:
Application.getApplication().invokeLater(new Runnable() {
public void run() {
progressScreen.close();
Dialog.alert("I am finished!");
}
});
It is similar to Android's:
handler.post(new Runnable() {
public void run() {
progressScreen.dismiss();
showDialog(DIALOG_TASK_FINISHED_ID);
}
});
Android has a much rich multi threading primitives. But you can achieve the same even in Blackberry with equal elegance. The solution I provide below is essentially the same as previous, but with a minor change. Waiter thread can be replaced with built-in utility to perform painting on UI thread using UiApplicaiton's invokeLater method. You don't actually need to "notify" anyone but just update the UI once a particular task is completed. Check the docs for more info.
Anyway, you can model your code along the lines:
class ProgressScreen extends FullScreen
{
LabelField _label;
public void start()
{
}
public void setMessage( final String message )
{
UiApplication.getApplication(
UiApplication.invokeLater(
new Runnable() {
_label.setText( message );
}
)
);
}
public void dismiss()
{
this.close();
}
}
interface WebserviceTask
{
int STATUS_CONDITIONS_NOT_SATISFIED = -3;
int STATUS_NET_ERR = -2;
int STATUS_FAILURE = -1;
int STATUS_SUCCESS = 0;
public int invoke();
}
public class Updater extends Thread
{
final int NUM_TASKS = 10;
WebServiceTask tasks[] = new WebServiceTask[ NUM_TASKS ];
WebServiceTask tasks[0] = new WebServiceTask(){
public int invoke()
{
int retCode = 0;
// invoke a particular web service
return STATUS_SUCCESS;
}
}
public void run()
{
ProgressScreen progress = new ProgressScreen();
progress.start();
for( int i=0; i < NUM_TASKS; i++ )
{
int retcode;
WebServiceTask t = tasks[i];
retcode = t.invoke();
String mesg;
switch( retcode )
{
case STATUS_SUCCESS: { mesg ="Task successfully completed!";} break;
case STATUS_NET_ERR: { mesg ="Could not connect to network";} break;
}
progress.setMessage(message);
}
progress.dismiss();
}
}
Note that I have provided only the stubs to give you an idea how you may accomplish. Let us know how it goes.

Resources