Re: BackgroundWorker in .NET CF 2.0



Well I haven't looked at the detail of all that as I don't have the time right now (but Chris has loads of time so he might...)

I certainly don't like all those statics, or all those empty catch handlers that swallow exceptions and not reporting them. Did you verify that the process stays up with remote process viewer like I suggested? Have you single stepped into the code when you close the form to see what code path it takes?

More importantly, why are you using a utility that was written to overcome a limitation of netcf v1/VS.NET2003 that has been rectified in v2/VS2005?
http://www.danielmoth.com/Blog/2004/11/debugwriteline.html

Cheers
Daniel
--
http://www.danielmoth.com/Blog/

"davis" <davisford@xxxxxxxxx> wrote in message news:1165769271.600656.141190@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Hi Daniel,

Thanks so much for the response. Here is a bit more precision, I hope.
I'm making use of this handy utility so I can log debug messages to
the command line on my development laptop ->

http://www.codeproject.com/csharp/compacttcptrace.asp?df=100&forumid=24359&exp=0&select=846907

This builds a .dll which I include in my application. It has a static
method to initialize itself where it reads an xml config file to get
the IP/Port of the remote console, and makes a TCP socket connection to
it.

This is expensive and timely when starting up my application. So I do
the following in my main form:

private Thread debug = null;

private void MainForm_Load(object sender, EventArgs e) {
#if DEBUG
debug = new Thread(new ThreadStart(initDebugConsole));
debug.Start();
#endif
}

private void initDebugConsole() {
// for debugging to a remote console
try {
TcpTraceListener.InstallTcpTraceListener();
Debug.WriteLine("Debug Console Ready...");
} catch (Exception e) {
/*
* try/catch block here, b/c if you don't have the tcp
server
* running to catch debug log statements, it crashes
the app.
*/
SetText(e.Message);
}
}

There is no while loop in the method for that ThreadStart, so once it
completes, it should complete. I believe the reason it hangs when I
try to re-deploy is that the socket is still open, despite the
TcpTraceListener code having the following:

public override void Close() {
if (stream != null) {
try {
SendString(end);
stream.Flush();
stream.Close();
stream = null;
} catch {
}
}
if (tcpClient != null) {
try {
tcpClient.Close();
tcpClient = null;
} catch (Exception) {
}
}
}

public void Dispose() {
Close();
}

I even added a static ShutDown( ) method to the TcpTraceListener code
that does the same thing:

public static void ShutDown() {
if (stream != null) {
SendString(end);
stream.Flush();
stream.Close();
stream = null;
}
if (tcpClient != null) {
tcpClient.Close();
tcpClient = null;
}
}

and in my form I do the following:

private Boolean shutdown() {
SetText("Shutting down....");
try {
TcpTraceListener.ShutDown( );
} catch (Exception) {
return false;
}
return true;
}

/// <summary>
/// Callback when form is closing
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected override void OnClosing(CancelEventArgs e) {
e.Cancel = shutdown();
base.OnClosing(e);
}

I guess the only thing I haven't commented on is the SendString(end);
call above in the ShutDown method -- this sends a poison pill to the
server to indicate the session is closing, so the server can print a
msg to the console that the client shut down.

If you can spot something in here that can cause the socket to stay
open, I'd love to hear it.

Thanks much in advance,
Davis


Daniel Moth wrote:
You have to be a bit more precise with your description.

"kill" an application, how? If it is just through the OK button then you are
not killing, it you are closing it, which is fine.

It sounds like your ShutDown method isn't really getting rid of the threads.
How are you trying to do that? If the thread is blocked on something you
will have to design a mechanism to *ask* the thread to terminate. An example
of how to use windows events to signal to a thread to terminate is here:
http://www.danielmoth.com/Blog/2004/11/dont-poll.html

Note that ThreadPool threads are not meant to be used for long running tasks
or for blocking operations. For that, you should use a dedicated thread.
Unless you are running against v1.0 of the NETCF where the pool has 256
rather than 25 (or you are on v2.0 but have tweaked the maximum).

It sounds like you are using the running programs list on the device to tell
if your app is running. That is not god enough as it only shows the top
level windows with a caption. Use the Remote Process Viewer from the Remote
Tools menu under the Visual Studio menu from your Start menu. Then you can
tell for sure if your app has exited or not.

Cheers
Daniel
--
http://www.danielmoth.com/Blog/

"davis" <davisford@xxxxxxxxx> wrote in message
news:1165728211.815824.117500@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> Hi Chris, Thanks for the response.
>
> Quick follow-up question...I'm not a wizard with this...still learning.
> I tried using a thread pool to get the job done.
>
> So, I have the method like this:
>
> private void initDebug(object state) {
>
> /* init debug TCP console here */
>
> }
>
> and in the main form constructor I have:
>
> ThreadPool.QueueUserWorkItem(initDebug);
>
> This seems to work ok...however when I kill the application, and I try
> to re-deploy, I notice that it fails because the DLL i use for tcp
> debug is in use.
>
> I learned the hard way about the MinimizeBox property on CF forms. So,
> I set this property to false, and I override the OnClosing method with
> this:
>
> protected override void OnClosing(CancelEventArgs e) {
> e.Cancel = ShutDown( );
> base.OnClosing(e);
> }
>
> where ShutDown( ) is my own method that tries to dispose of all
> threads, sockets, etc.
>
> It catches any exceptions and returns false if caught, otherwise it
> returns true.
>
> So, when I close the application, I see that the process is not listed
> in the running processes on the PocketPc, but still, something has a
> hold on this DLL, which leads me to have to reboot the device every
> time.
>
> Any ideas on what I'm doing wrong here?
>
> Thanks in advance,
> davis
>
>
> <ctacke/> wrote:
>> Create a thread. It's really not difficult. But there's also the >> SDF:
>>
>> http://www.opennetcf.com/library/sdf/OpenNETCF.ComponentModel.BackgroundWorkerMembers.html
>>
>>
>> --
>> Chris Tacke
>> OpenNETCF Consulting
>> Managed Code in the Embedded World
>> www.opennetcf.com
>> --
>>
>>
>>
>>
>> "davis" <davisford@xxxxxxxxx> wrote in message
>> news:1165721904.112835.165860@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
>> > Hi, I guess there is no BackgroundWorker in CF 2.0, but is there >> > some
>> > other easy way to launch a quick background thread task from the UI?
>> >
>> > I have a debug console logger, and it takes a while to fire up and
>> > connect to a remote TCP server...and when it starts up, it causes
>> > program start lag.
>> >
>> > I could --
>> >
>> > a) Add a UI control to initialize it
>> > b) Spawn a new Thread(ThreadStart(initLogger));
>> >
>> > Is there a better way?
>> >
>


.