Processing halting

J

John Hatpin

Another somewhat newbie question about C# processing stopping in the
middle of code. I've pasted in a section of code at the end of this
post which illustrates the problem. For ease of reading, I've replaced
tabs with spaces by hand - I think I've got that right.

Within the code, I have debug.write statements, which show where the
processing is failing. This section of code is called repeatedly, with
different data, and almost never reaches the end. It usually stops
after having printed either "4" or "c", outputting eg:

....12341234abcabcabcabc12341234...

1, 2 and 3 are output earlier in the code. "5" is almost never
printed, despite many hundreds of runs through with different data.

I appreciate that the code is not good - there are multiple tests for
nulls in the TEF object which are probably unnecessary, for example -
but I'm working without any documentation and I'd rather test every
condition than have it fail silently (see below).

Now, obviously this is only a small part of the app. Some of those
calls are to library methods which I don't even have the source for.
However, there is something I'm fundamentally not understanding here.

How can, for example, the line printing "c" be run, but not the line
printing "d"? All that's in between them is the closing brace for the
foreach() block - if it executes the contents of the foreach, then why
does it not execute the statement after?

(On a personal note, I do find it extremely frustrating and
demotivating that C# code just stops like this without producing any
kind of error message, even run (as in this case) in debug mode. The
only reason I knew to start looking for a problem in the first place
was because I saw symptoms of later code (after the "5") not being
run. This seems to be normal behaviour, this silent failing, but I do
find it maddening.)

The environment is Windows XP Home, SharpDevelop and everything
up-to-date.

Thanks in advance for your help.


System.Diagnostics.Debug.Write("4") ;
lock(Prim)
{
if (!Prim.Textures.Equals(null))
{
if (Prim.Textures.FaceTextures.Length > 0)
{
foreach(Primitive.TextureEntryFace TEF in
Prim.Textures.FaceTextures)
{
if (!TEF.Equals(null))
{
if (!TEF.TextureID.Equals(null))
{
if (TEF.TextureID != UUID.Zero)
{
System.Diagnostics.Debug.Write("a") ;

Texture T = InsertOrSelectTexture(TEF.TextureID) ;

if (!tItem.FaceTextures.Contains(T))
tItem.FaceTextures.Add(T) ;

Client.Assets.RequestImage(TEF.TextureID, UpdateTexture)
;

if (!T.Items.Contains(tItem))
T.Items.Add(tItem) ;

System.Diagnostics.Debug.Write("b") ;
}
}
}
System.Diagnostics.Debug.Write("c") ;
}
System.Diagnostics.Debug.Write("d") ;
}
}
}
System.Diagnostics.Debug.Print("5") ;
 
T

Tom Shelton

John Hatpin presented the following explanation :
Another somewhat newbie question about C# processing stopping in the
middle of code. I've pasted in a section of code at the end of this
post which illustrates the problem. For ease of reading, I've replaced
tabs with spaces by hand - I think I've got that right.

Within the code, I have debug.write statements, which show where the
processing is failing. This section of code is called repeatedly, with
different data, and almost never reaches the end. It usually stops
after having printed either "4" or "c", outputting eg:

...12341234abcabcabcabc12341234...

1, 2 and 3 are output earlier in the code. "5" is almost never
printed, despite many hundreds of runs through with different data.

I appreciate that the code is not good - there are multiple tests for
nulls in the TEF object which are probably unnecessary, for example -
but I'm working without any documentation and I'd rather test every
condition than have it fail silently (see below).

Now, obviously this is only a small part of the app. Some of those
calls are to library methods which I don't even have the source for.
However, there is something I'm fundamentally not understanding here.

How can, for example, the line printing "c" be run, but not the line
printing "d"? All that's in between them is the closing brace for the
foreach() block - if it executes the contents of the foreach, then why
does it not execute the statement after?

(On a personal note, I do find it extremely frustrating and
demotivating that C# code just stops like this without producing any
kind of error message, even run (as in this case) in debug mode. The
only reason I knew to start looking for a problem in the first place
was because I saw symptoms of later code (after the "5") not being
run. This seems to be normal behaviour, this silent failing, but I do
find it maddening.)

The environment is Windows XP Home, SharpDevelop and everything
up-to-date.

Thanks in advance for your help.


System.Diagnostics.Debug.Write("4") ;
lock(Prim)
{
if (!Prim.Textures.Equals(null))
{
if (Prim.Textures.FaceTextures.Length > 0)
{
foreach(Primitive.TextureEntryFace TEF in
Prim.Textures.FaceTextures)
{
if (!TEF.Equals(null))
{
if (!TEF.TextureID.Equals(null))
{
if (TEF.TextureID != UUID.Zero)
{
System.Diagnostics.Debug.Write("a") ;

Texture T = InsertOrSelectTexture(TEF.TextureID) ;

if (!tItem.FaceTextures.Contains(T))
tItem.FaceTextures.Add(T) ;

Client.Assets.RequestImage(TEF.TextureID, UpdateTexture)
;

if (!T.Items.Contains(tItem))
T.Items.Add(tItem) ;

System.Diagnostics.Debug.Write("b") ;
}
}
}
System.Diagnostics.Debug.Write("c") ;
}
System.Diagnostics.Debug.Write("d") ;
}
}
}
System.Diagnostics.Debug.Print("5") ;

Is there threading going on? I see the lock statement there. What
your describing sounds suspiciously like a dead lock.
 
J

John Hatpin

Tom said:
John Hatpin presented the following explanation :

Is there threading going on? I see the lock statement there. What
your describing sounds suspiciously like a dead lock.

I've not explicitly introduced any threading - the lock statement is
desperation! If I don't do any explicit threading, is it unnecessary?
 
J

John Hatpin

Finally got back to dealing with this ...

Peter said:
John said:
[...]
How can, for example, the line printing "c" be run, but not the line
printing "d"? All that's in between them is the closing brace for the
foreach() block - if it executes the contents of the foreach, then why
does it not execute the statement after?

Impossible to say without a concise-but-complete code example that
reliably demonstrates the problem.

Unfortunately, I don't have access to all the source code - much of it
is buried in libraries.
Given the code you've posted and that the code apparently does go back
and execute the loop again (i.e. it's not just stuck there), it appears
most likely that an exception is being thrown (either a
ThreadAbortException generated elsewhere, or perhaps an exception being
thrown by the MoveNext() method of the enumerator returned by the
Prim.Textures.FaceTextures). And since the program continues to run, if
that's what's happening, you must have a try/catch block higher in the
call stack that is handling the exception.

But that's pure speculation, since you haven't provided a proper code
example.

However, you have made me wonder if there is a problem with the
implementation of the enumerator, and I'll look into ways of bypassing
the foreach().
Silent failures are only "normal" if you have written code to catch
failures and prevent the framework from seeing them.

There's no reason to blame C# or to even be frustrated by the language.
Frankly, the likelihood that this is a C# issue per se is extremely
low. And for sure, until you've actually diagnosed the problem and
completely understand it, you have no basis for making that assumption.

The reason I associate this type of problem with C# is that I've never
encountered anything like it before in 36 years of programming. Then
again, I've not coded in .NET before, nor do I have any experience of,
say, C++ or Java.
If and when you find the problem (or post a concise-but-complete code
example that reliably reproduces the problem, so that one of the rest of
us reading the newsgroup can find the problem), I'm sure it will turn
out to be a coding error, either in your own code or in the library
you're using.

For what it's worth, you can configure the Visual Studio debugger to
stop on _all_ exceptions, not just those that are unhandled. So if you
can run this code in the debugger and reproduce the problem, if it is in
fact an exception being thrown and caught, you can easily find that out.

I don't seem to be able to do that with SharpDevelop, but I'll
research that some more. If, in the end, it means I have to use VS, so
be it.

Thanks to everyone for your help.
 

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