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
Susan wrote:
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" wrote:
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