Asynchronous Process Question

G

Guest

I have a process that takes a while to run so I have it running
asynchronously so that the user can continue working. My question is that I
want to killl the process if the user changes the search parameters before
the callback method is called. Any ideas of how to do this or if it even
matters? I did not know if calling the asynch process a new time kills the
previous one or not.

Thank you for your help.
Susan
 
J

John Duval

Susan said:
I have a process that takes a while to run so I have it running
asynchronously so that the user can continue working. My question is that I
want to killl the process if the user changes the search parameters before
the callback method is called. Any ideas of how to do this or if it even
matters? I did not know if calling the asynch process a new time kills the
previous one or not.

Thank you for your help.
Susan

Hi Susan,
Can you post some code? It seems like you can just kill the process
using the object reference that you have:

static void Main(string[] args)
{
Process p = new Process();
p.StartInfo.FileName = @"C:\WINDOWS\system32\notepad.exe";
p.Start();

Console.WriteLine("press enter to kill process");
Console.ReadLine();
p.Kill();
return;
}

Hope this helps,
John
 
M

Michael Nemtsev

Hello Susan,

Theoretically you can dive into message sing objects that are performing
async calls where is the cancellation located
but practically it's very hard to do, you need to intercept calls, context
and etc.

standarc acyns handler classes don't have functionality to cancell async call

S> I have a process that takes a while to run so I have it running
S> asynchronously so that the user can continue working. My question is
S> that I want to killl the process if the user changes the search
S> parameters before the callback method is called. Any ideas of how to
S> do this or if it even matters? I did not know if calling the asynch
S> process a new time kills the previous one or not.
S>
S> Thank you for your help.
S> Susan
---
WBR,
Michael Nemtsev :: blog: http://spaces.msn.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
 
G

Guest

I do not think that will work. Here's code snippets:
private CountDelegate dDeleg;

private void GetResults ()
{
/*get the actual results from database, but in limited number (25 per
page) to
increase response time*/

if (_newQuery)
{
cDeleg = new CountDelegate(Count);
AsyncCallback cb = new AsyncCallback (CountCallback);
cDeleg.BeginInvoke (tgts, cb, "countDelegate");
}
}

private void CountCallback (IAsyncResult ar)
{
cDeleg.EndInvoke (ar);
SetCount(); //just something letting the user know how many results there
are
}

I didn't know if there was a way to force the end invoke even though the
process is not completed. I know that there is not cancel even, but am hoping
there is a way to similate one... Any ideas?

Thank you,
Susan

John Duval said:
I have a process that takes a while to run so I have it running
asynchronously so that the user can continue working. My question is that I
want to killl the process if the user changes the search parameters before
the callback method is called. Any ideas of how to do this or if it even
matters? I did not know if calling the asynch process a new time kills the
previous one or not.

Thank you for your help.
Susan

Hi Susan,
Can you post some code? It seems like you can just kill the process
using the object reference that you have:

static void Main(string[] args)
{
Process p = new Process();
p.StartInfo.FileName = @"C:\WINDOWS\system32\notepad.exe";
p.Start();

Console.WriteLine("press enter to kill process");
Console.ReadLine();
p.Kill();
return;
}

Hope this helps,
John
 
G

Guest

Darn. I was hoping there was an easy work around. I guess I'll change it to a
thread then.... Thank you. :)
 
P

Pieter Breed

Hi Susan,

(sorry about the bad spelling... its late, and I am not a native
english speaker ;) )

Fact of the matter is this: You are now doing multithreaded
programming. The best way to go about it is to embrace the fact and now
be aware of the issues inherent in the paradigm.

what you should do (for some undefined value of "should") is keep 2
booleans around that keeps track of whether the async process should
stop or not, and whether it is running or not.

These 2 bools should both be locked in the standard way. Here I will
show you how:

private readonly object mSomeBooleanLock = new object();
private bool mLockedSomeBool = false; // some sane default value here

private bool SomeBoolValue()
{
bool result;
lock(mSomeBooleanLock)
{
result = mLockedSomeBool;
}
return result;
}

private void SetSomeBoolValue(bool pNewValue)
{
lock(mSomeBooleanLock)
{
mLockedSomeBool = pNewValue;
}
}


btw - put all of this in a new class that will "host" your background
process. Then make a new instance for every new search.

Now: In this class, have methods StartBackgroundJob() and EndJob().

Startjob should look something like this:
private void StartBackgroundActual(object[] pParams)
{
SetMustStop(false);
SetIsRunning(true);

bool workIsFinished = false;

while(!MustStop() || workIsFinished)
{
// do some quantum of work here
// use the pParams here to tune your search
// sowe workIsFinished = true sometime
}

if(workIsFinished)
{
// provide feedback with the results in some way
// remember this will call on a thread different from your main
ui thread
// handle with care
}

SetIsRunning(false);
}

delegate void VoidMethod();
public void StartBackgroundJob(object[] pParams)
{
VoidMethod asyncCall = delegate()
{
StartBackgroundActual(pParams);
};
asyncCall.BeginInvoke(
1,
delegate(IAsyncResult pAsyncResult)
{
asyncCall.EndInvoke(pAsyncResult);
},
null);
}

public void Endjob(bool pMustBlock)
{
SetMustStop(true);
if (pMustBlock)
{
while(IsRunning())
{
Thread.Sleep(350); // some random value... don't set it to
some power of 2. cannot remember why exactly anymore
}
}
}

Everytime that your user changes his search parameters, set the old
background job (of which you kept a handle around) to stop. Then
instantiate a new instance, set it to start running with the new
parameters received from the user.

I would seriously suggest that you read this piece:
http://www.yoda.arachsys.com/csharp/threads/index.shtml

It is the canonical work on multi-threading (free and available online)

The other piece of advice that helped me when i learned to thread was
this: investigate anonymous methods with the aim of using them for
closures. The technique helps THIIIIIIIIIIS much when you are coding to
different threads.

Regards,
Pieter
I do not think that will work. Here's code snippets:
private CountDelegate dDeleg;

private void GetResults ()
{
/*get the actual results from database, but in limited number (25 per
page) to
increase response time*/

if (_newQuery)
{
cDeleg = new CountDelegate(Count);
AsyncCallback cb = new AsyncCallback (CountCallback);
cDeleg.BeginInvoke (tgts, cb, "countDelegate");
}
}

private void CountCallback (IAsyncResult ar)
{
cDeleg.EndInvoke (ar);
SetCount(); //just something letting the user know how many results there
are
}

I didn't know if there was a way to force the end invoke even though the
process is not completed. I know that there is not cancel even, but am hoping
there is a way to similate one... Any ideas?

Thank you,
Susan

John Duval said:
I have a process that takes a while to run so I have it running
asynchronously so that the user can continue working. My question is that I
want to killl the process if the user changes the search parameters before
the callback method is called. Any ideas of how to do this or if it even
matters? I did not know if calling the asynch process a new time kills the
previous one or not.

Thank you for your help.
Susan

Hi Susan,
Can you post some code? It seems like you can just kill the process
using the object reference that you have:

static void Main(string[] args)
{
Process p = new Process();
p.StartInfo.FileName = @"C:\WINDOWS\system32\notepad.exe";
p.Start();

Console.WriteLine("press enter to kill process");
Console.ReadLine();
p.Kill();
return;
}

Hope this helps,
John
 
C

Carl Daniel [VC++ MVP]

Susan said:
Darn. I was hoping there was an easy work around. I guess I'll change it
to a
thread then.... Thank you. :)

It's no easier using a Thread of your own than doing work in a method
invoked by an async delegate. The reason it's no easier - you DON'T want to
use Thread.Abort() to kill your worker thread. Rather, in either case (your
thread or async delegate), you need to send a "message" to your long-running
operation requesting that it stop. That "message" is typically just a
shared bool variable (as the excellent response by Pieter Breed outlines),
but it could also be a window message, a post to a Win32 Event or Semaphore,
or whatever is appropriate for the task at hand. Your long-running
operation then cooperatively stops when it's asked to, and sends a "message"
back to the requestor acknowledging the stop request.

-cd
 
J

John Duval

Hi Susan,
I see what you're asking now... I was thrown off when you said you were
starting a 'process' asynchronously. :)

I agree with what the others have posted -- have the long-running
operation periodically check to see if it should stop. This can done
by a shared boolean flag, signalling an event, etc...

John
I do not think that will work. Here's code snippets:
private CountDelegate dDeleg;

private void GetResults ()
{
/*get the actual results from database, but in limited number (25 per
page) to
increase response time*/

if (_newQuery)
{
cDeleg = new CountDelegate(Count);
AsyncCallback cb = new AsyncCallback (CountCallback);
cDeleg.BeginInvoke (tgts, cb, "countDelegate");
}
}

private void CountCallback (IAsyncResult ar)
{
cDeleg.EndInvoke (ar);
SetCount(); //just something letting the user know how many results there
are
}

I didn't know if there was a way to force the end invoke even though the
process is not completed. I know that there is not cancel even, but am hoping
there is a way to similate one... Any ideas?

Thank you,
Susan

John Duval said:
I have a process that takes a while to run so I have it running
asynchronously so that the user can continue working. My question is that I
want to killl the process if the user changes the search parameters before
the callback method is called. Any ideas of how to do this or if it even
matters? I did not know if calling the asynch process a new time kills the
previous one or not.

Thank you for your help.
Susan

Hi Susan,
Can you post some code? It seems like you can just kill the process
using the object reference that you have:

static void Main(string[] args)
{
Process p = new Process();
p.StartInfo.FileName = @"C:\WINDOWS\system32\notepad.exe";
p.Start();

Console.WriteLine("press enter to kill process");
Console.ReadLine();
p.Kill();
return;
}

Hope this helps,
John
 
G

Guest

Since the same process, but with different parameters would be started
causing the need to stop the previous process. Basically, the user would
click on one item to get the results and then change their mind and click on
another item. How do I differentiate or make sure the one is stopped before I
start the next one? The part of the process that takes the time is waiting
for the result back from the database. Do I just do a while not complete (or
back from the database at least) wait to send the second set of info? The
chance is very small that the user would change their mind quickly enough for
the database to not have returned, but do not want to take chances if you
know what I mean. :)

Thank you,
Susan

:
 
P

Pieter Breed

Hi Susan,

Actually you don't /really/ need to stop the old database query at all.
It can simply finish processing and return to a place where nobody is
interested in its results anymore.

As long as you represent your queries as seperate class instances, and
keep a reference only to the last query (and as long as those threads
actually do finish!) you can simply keep on waiting for the last query
to finish.

If you are talking about a db query, there isn't really any efficient
way in which you can interrupt the query, since the query is running on
another physical machine. (Contrast this to a filesystem search which
is local and slow) If the queries are as quick as you say, then simply
letting them finish won't really cost you much either.

Hope this helps,
Pieter
 
G

Guest

Hi Pieter,

I realize i am replying to a pretty old discussion thread. But i am facing
an asynchronous issue and of all the replies in the discussion board, i felt
yours was the most sensible one. I thought maybe you can give me some
pointers for my issue.

I have to make multiple calls (about 400K) to a webservice which returns a
string. And currently it takes about a week to make all the calls. Instead of
waiting for the webservice result before i make the next call, I rather want
to make the calls and let the results comeback at its own pace. I used
Asynchronous calling and callback method, but it does not seems to work. I am
sure, asynchronous way will improve my program execution exponentially. I
would appreciate if someone can help me with this. And by the way, i did not
see an Begin and End methods.


Here is my method which is making the webservice calls.

public static Boolean WebServiceCallsXY(string x, string y)
{
try
{
UsernameToken token = new UsernameToken("AAA", "BBB",
PasswordOption.SendPlainText);
MbrSrvWse wseProxy = new MbrSrvWse ();
wseProxy.SetClientCredential<UsernameToken>(token);
wseProxy.SetPolicy("ProvideUsernameToken");

IndividualDetailRequest test = new IndividualDetailRequest();
test.UserId = x;
test.Pin = y;
IndividualDetailResponse response =
wseProxy.IndividualDetail(test);

if (response.Result.Length > 0)
{
if (response.Result.ToString().ToLower().Equals("a"))
{
return true;
}
if (response.Result.ToString().ToLower().Equals("b"))
{
return false;
}
}
return false;
}
catch (Exception e)
{
Console.WriteLine("The following error '{0}' -------- {1} :
{2} ", e.Message, e.StackTrace, x);
return false;
}
}

--
Kalyan


Pieter Breed said:
Hi Susan,

(sorry about the bad spelling... its late, and I am not a native
english speaker ;) )

Fact of the matter is this: You are now doing multithreaded
programming. The best way to go about it is to embrace the fact and now
be aware of the issues inherent in the paradigm.

what you should do (for some undefined value of "should") is keep 2
booleans around that keeps track of whether the async process should
stop or not, and whether it is running or not.

These 2 bools should both be locked in the standard way. Here I will
show you how:

private readonly object mSomeBooleanLock = new object();
private bool mLockedSomeBool = false; // some sane default value here

private bool SomeBoolValue()
{
bool result;
lock(mSomeBooleanLock)
{
result = mLockedSomeBool;
}
return result;
}

private void SetSomeBoolValue(bool pNewValue)
{
lock(mSomeBooleanLock)
{
mLockedSomeBool = pNewValue;
}
}


btw - put all of this in a new class that will "host" your background
process. Then make a new instance for every new search.

Now: In this class, have methods StartBackgroundJob() and EndJob().

Startjob should look something like this:
private void StartBackgroundActual(object[] pParams)
{
SetMustStop(false);
SetIsRunning(true);

bool workIsFinished = false;

while(!MustStop() || workIsFinished)
{
// do some quantum of work here
// use the pParams here to tune your search
// sowe workIsFinished = true sometime
}

if(workIsFinished)
{
// provide feedback with the results in some way
// remember this will call on a thread different from your main
ui thread
// handle with care
}

SetIsRunning(false);
}

delegate void VoidMethod();
public void StartBackgroundJob(object[] pParams)
{
VoidMethod asyncCall = delegate()
{
StartBackgroundActual(pParams);
};
asyncCall.BeginInvoke(
1,
delegate(IAsyncResult pAsyncResult)
{
asyncCall.EndInvoke(pAsyncResult);
},
null);
}

public void Endjob(bool pMustBlock)
{
SetMustStop(true);
if (pMustBlock)
{
while(IsRunning())
{
Thread.Sleep(350); // some random value... don't set it to
some power of 2. cannot remember why exactly anymore
}
}
}

Everytime that your user changes his search parameters, set the old
background job (of which you kept a handle around) to stop. Then
instantiate a new instance, set it to start running with the new
parameters received from the user.

I would seriously suggest that you read this piece:
http://www.yoda.arachsys.com/csharp/threads/index.shtml

It is the canonical work on multi-threading (free and available online)

The other piece of advice that helped me when i learned to thread was
this: investigate anonymous methods with the aim of using them for
closures. The technique helps THIIIIIIIIIIS much when you are coding to
different threads.

Regards,
Pieter
I do not think that will work. Here's code snippets:
private CountDelegate dDeleg;

private void GetResults ()
{
/*get the actual results from database, but in limited number (25 per
page) to
increase response time*/

if (_newQuery)
{
cDeleg = new CountDelegate(Count);
AsyncCallback cb = new AsyncCallback (CountCallback);
cDeleg.BeginInvoke (tgts, cb, "countDelegate");
}
}

private void CountCallback (IAsyncResult ar)
{
cDeleg.EndInvoke (ar);
SetCount(); //just something letting the user know how many results there
are
}

I didn't know if there was a way to force the end invoke even though the
process is not completed. I know that there is not cancel even, but am hoping
there is a way to similate one... Any ideas?

Thank you,
Susan

John Duval said:
Susan wrote:
I have a process that takes a while to run so I have it running
asynchronously so that the user can continue working. My question is that I
want to killl the process if the user changes the search parameters before
the callback method is called. Any ideas of how to do this or if it even
matters? I did not know if calling the asynch process a new time kills the
previous one or not.

Thank you for your help.
Susan

Hi Susan,
Can you post some code? It seems like you can just kill the process
using the object reference that you have:

static void Main(string[] args)
{
Process p = new Process();
p.StartInfo.FileName = @"C:\WINDOWS\system32\notepad.exe";
p.Start();

Console.WriteLine("press enter to kill process");
Console.ReadLine();
p.Kill();
return;
}

Hope this helps,
John
 
J

Jon Skeet [C# MVP]

Kalyan said:
I realize i am replying to a pretty old discussion thread. But i am facing
an asynchronous issue and of all the replies in the discussion board, i felt
yours was the most sensible one. I thought maybe you can give me some
pointers for my issue.

I have to make multiple calls (about 400K) to a webservice which returns a
string. And currently it takes about a week to make all the calls. Instead of
waiting for the webservice result before i make the next call, I rather want
to make the calls and let the results comeback at its own pace. I used
Asynchronous calling and callback method, but it does not seems to work. I am
sure, asynchronous way will improve my program execution exponentially. I
would appreciate if someone can help me with this. And by the way, i did not
see an Begin and End methods.

The proxy generated for the web service should have the BeginXXX and
EndXXX methods. However, if you have problems with that sort of
operation you could just use the ThreadPool and QueueUserWorkItem, then
make the call synchronously there.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top