C# is a relatively new language. And it's entirely possible that in the past, you used to dabble in BASIC. I first programmed in Amstrad BASIC on my trusty CPC464, AMOS on the Amiga, QBasic on the PC, then Visual basic 3, 5, 6... and then C#.
In BASIC, a popular way of combining a string would be to use the + operator.
For example:
' BASIC
PRINT "HELLO " + "WORLD"
I used this technique with QBASIC, Visual Basic 3-6, and never had any issues. It also works in C#
// C#
Console.WriteLine("Hello " + "World");
It even works in Visual Basic
' Visual Basic
Console.WriteLine("Hello " + "World")
This code will not give you a compile error. It will run and work as expected. However it is not the recommended method of doing it. This is because it sometimes doesn't work.
' Visual Basic
Dim age As Integer = 26
Console.WriteLine("Your age: " + age)
Looks good. In C#, this syntax would definitely work. However if you run this in Visual Basic, you will get a runtime error.
Conversion from string "Your age:" to type 'Double' is not valid.
It seems to handle + as an arithmetic operator. Why is this useful? I have no idea. It's something to note though, that Visual Basic treats + as a way to combine numbers, unless you are combining two strings.
Incidentally,
' Visual Basic
Dim age As Integer = 26
Console.WriteLine("25" + age)
will run fine and give you 51. I just can't imagine a situation where you'd ever do this.
What really bugs me is the consistency. If + converts things to Double, why does combining two strings "Hello" and "World" work?
All I can say is be careful, especially when converting code. If you do what I do and copy and paste C# code into your VB solution then fix errors, this problem won't flag up until runtime, when it may or may not work.
The correct way to handle this problem in Visual Basic is to use the & operator instead. Simple as that.
' Visual Basic
Dim age As Integer = 26
Console.WriteLine("Your age: " & age)
Console.WriteLine("25" & age)
The result is
Your age: 26
2526
Now, onto the reason why this caused me so much grief...
I was writing some unit tests for a piece of code, and that code involved lambda expressions. This is a pretty new thing, especially as far as Visual Basic is concerned (it's generally one step behind C# for new features).
When you're testing, generally your tests either pass or fail. However, just occasionally you may get the dreaded error:
The agent process was stopped
Your test will mysteriously break with this error, and no further information. In my case, I discovered this was to do with a BackgroundWorker that was hooked into a lambda expression. After running it asynchronously, and doing an e.WaitOne to wait for it to return, it didn't. This caused the test to stop with this error. There was no futher information.
Trying to run the test in debug mode didn't do anything at all; Visual Studio did nothing. Manually bringing up the test window showed the test had been aborted.
Taking a step back:
BackgroundWorker allows you to run some code asynchronously (in the background) so you can get on with other things. Useful for if something takes a while to do.
More information about BackgroundWorker on MSDN
Lambda expressions are a vast topic, but in this case I can create an event handler, and instead of pointing it at a method (such as button_click), I can define the code myself, which is faster and neater especially if its just one or two lines.
More information about Lambda expressions on MSDN
For example:
// C#
bw.DoWork += (o, args) =>
{
// Code here
}
' Visual Basic
AddHandler bw.DoWork,
Sub(o, args)
' Code here
End Sub
So it turns out, that if your lambda expression generates a runtime error, you don't get any feedback on it. You don't get the usual exception dialogue appearing and showing you what went wrong. Instead, your test produces "The agent process was stopped" and leaves you wondering why.
Solution
These two topics tie together because my lambda expression contained this code:
' Visual Basic
OnDataModificationCompleted(True,
"Create new employee with ID: " + DirectCast(args.Result, Employee).ID,
DirectCast(args.Result, Employee).ID)
As soon as I changed the + into a &, the test error went away.
So if you're reading this because you're getting "The agent process was stopped", it's quite possibly a threading issue. In my case, the lambda expression generated a runtime error which caused it to never call the OnDataModificationCompleted method and let the BackgroundWorker know that the process had finished executing. The other part of my code sat waiting indefinitely, and made the test method generate that error (rather than passing or failing).
No comments:
Post a Comment