Wednesday, July 20, 2011
Ghosts and Time Bombs
Monday, June 27, 2011
Linq: Creating new objects from selects and joins
Thursday, March 25, 2010
LCNUG - Visual Programming Language with Robotics Studio
Last night, Lance Larson, president of the Madison .NET User Group, presented at LCNUG on Visual Programming Language (VPL) with Robotics Studio. It was an active presentation - he even had robots moving around the room!
Two things that really got my attention:
- VPL applies to more than just robots. Many businesses continually hit the problem "how can I have a non-technical person still get technical things done?" For example, they'd like a business analyst program a workflow or rules engine without needing to actually code. Many workflow-related products provide some kind of drag & drop interface (like making a flowchart in Visio) to effectively write a program, but such an interface is difficult to build. It gets especially complicated when you have variables, conditions, looping, etc... Microsoft's VPL is powerful, and I wonder if it will be reused for their workflow products too.
- Being surrounded by software, it's refreshing to see the hardware part of engineering - like physical robots that follow programming instructions.
Thanks Lance!
Tuesday, March 2, 2010
Visual Studio 2008 hanging
There's a lot of reasons that Visual Studio hangs. It was hanging for me the other day when I tried to open, and I had a clean checkout. One solution that solved my current problem (thanks to a co-worker):
- Close VS, delete the *.suo file, and try to re-open. I'm sure there's a reason why,
2 seconds later, VS was up and running.
Sunday, January 24, 2010
Is this code broken?
What constitutes broken code? Everyone agrees that code that crashes in production and threatens to have developers fired is indeed broken. But where's the line? Is the following code broken:
- The code logs incorrect data in an error log file?
- The code displays incorrect values in a label (like a mis-formatted date)?
- If a certain rare case occurs (like a button is pressed at exactly 12:00AM, or an uploaded file size is exactly 1.00 MB), then the code crashes?
- The code has mis-leading names for variables and methods. For example, it has a method "IsNumber" that checks only for integers, or "IsLetter" that allows for special characters? Say the current program calls the method with correct data so that the app never crashes?
In all these cases, say the application essentially "works" and handles the main use cases.
The problem is maintenance. Maintaining and extending code is an expensive part of the total cost of ownership. You could spend hours tracking down a single erroneous line of code. Code that is low quality (tons of copy & paste, misnamed methods, misleading logic, etc...) is going to be a fortune to maintain. On the other hand, certain functional errors that have zero impact on the business can perhaps be documented as "known-issues" (i.e. the month is formatted in a label with a preceding zero like "03" instead of just "3".
I'd say it comes down to the business, and the code is broken if it costs the business more than it should - whether it be via maintenance costs or functional errors that hinder the end users. Perhaps the question isn't as much "is this code broken", but "how can we maximize the business-value of this code?"
Thursday, October 8, 2009
Can you still be technical if you don't code?
Can you still be technical if you don't code? A lot of developers have a passion for the technology, do a great job in their current role of implementing solutions (which requires coding), and then get "promoted" into some "big picture" role that no longer does implementation - ironically the thing they did so well at. These higher-level roles often do lots of non-trivial things, but not actual coding. For example:
- Infrastructure (Servers, SAN space, database access, network access)
- Design decisions
- Dealing with legacy code
- Handling outsourcing, insourcing, consultants
- Build-vs-buy
- Vendor evaluations/score card; integrate the vendor's product into your own
- Coordinate large-scale integration of many apps from different environments
- Coordination among multiple product life cycles
- Writing guidance docs
- Code reviews
- Occasional prototypes
- Configuration
On one hand, these types of tasks require technical knowledge in that you wouldn't expect a non-technical person to perform them. On the other hand, they don't seem in the same category as hands-on coding.
What do you think - can you be technical (or remain technical) without actually writing code?
Tuesday, September 22, 2009
ConnectionTimeout vs. CommandTimeout
SQL timeouts can be very annoying, especially for internal development tools where performance isn't critical.
A lot of developers will try fixing this by modifying the connection string by appending "Connect Timeout=300". Normally this is easy because the connection string is stored in some config file.
However, it still usually fails. This is because there's a big difference between SqlConnection.ConnectionTimeout and SqlCommand.CommandTimeout.
If you're running a command, like a snippet of SQL or a stored proc, then your code needs to set the CommandTimeout. Something like so:
SqlConnection con = new SqlConnection(strDbCon);
SqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = strText;
cmd.CommandTimeout = 10000; //no relation to con.ConnectionTimeout
Obviously, that's very minimalist code, but that's the general idea. For a robust data access layer, you'd make the timeout configurable.
Monday, April 27, 2009
BOOK: Patterns of Enterprise Application Architecture
I remember when Martin Fowler's Patterns of Enterprise Application Architecture came out back in 2002. I constantly heard good things, but never got around to reading it. Finally, I buckled down and went through it, and I'm glad I did.
Perhaps the biggest thing I liked about the book was the common vocabulary. Whenever I look at popular community projects (such as Enterprise Library, CLSA, or .NetTiers), or just read star bloggers, ones keeps hearing about all these pattern names (ActiveRecord, Gateway. Lazy Load, Repository, Registry, Service Layer, etc...). While gradually you pick them up, it's convenient just injecting them into your brain all at once.
I also thought his chapters on concurrency were excellent, especially how he explains the difference between an optimistic lock and pessimistic lock. (My simplified interpretation is that an optimistic lock is "optimistic" in that it assumes conflicts are either rare, or easy to resolve, and hence checks for conflicts at the end of a transaction. On the other hand, a pessimistic lock is "pessimistic" in that it assumes conflicts are either common, or very expensive to resolve, and hence prevents the conflict from ever occurring by locking at the beginning of a transaction).
He's also very "no-holds-barred" for doing things the best way. For example in the Metedata Mapping pattern he emphasizes using code generation or reflection - two concepts that for some reason many developers seem reluctant to use.
Lastly, reading a solid book like this just helps you think more about enterprise patterns as you go through your daily coding, and that's a valuable thing.
Sunday, April 26, 2009
Structs vs. Classes - seeing the functional difference
There's a lot written about the difference between classes and structs, and comparing the two.
One thing I find helpful to really "get it" is to whip up a quick unit test, and functionally see the differences. While classes (being reference types) and structs (being value types) will have different memory and performance implications, it seems most devs are initially concerned with how they're functionally different, and they worry about performance "later".
Here's an example showing both a struct and a class object being passed into some method and having their property updated. The struct, being a value type, is copied when sent into the method, and hence the property doesn't "persist" outside of the method (the copy is discarded, the original left untouched). However, the class sends in a reference, and therefore the method is pointing to the same instance as the host caller, and hence the update "persists" for the class..
[TestMethod]
public void TestMethod1()
{
MyStruct s = new MyStruct();
s.Name = "Struct1";
MyClass c = new MyClass();
c.Name = "Class1";
UpdateStruct(s);
UpdateClass(c);
Assert.AreEqual("Struct1", s.Name);
Assert.AreEqual("newClass", c.Name);
}
private void UpdateStruct(MyStruct s)
{
s.Name = "newStruct";
}
private void UpdateClass(MyClass c)
{
c.Name = "newClass";
}
public struct MyStruct
{
public string Name { get; set; }
}
public class MyClass
{
public string Name { get; set; }
}
You could write tests for similar things - like showing how structs don't allow inheritance (which actually wouldn't even compile), but do allow interfaces. You can drill down even further by stepping through in the debugger, or checking Visual Studio's performance wizard.
Wednesday, March 4, 2009
Refactoring SQL code with file includes and variables
Everyone who maintains code knows that duplicated code is bad. While OOP languages like C# (and even xml "languages" like MSBuild) provide ways to refactor, SQL seems lacking in such features. If you run a similarity-analyzer (like Simian), you can probably see large amounts of duplicated code. Two common refactoring techniques to help with this would be:
- Dynamic include – Include one snippet within another. For example, we could have a chunk of code that is duplicated in a stored proc, and a table function.
- Variables – We can abstract any SQL code (table names, sql commands) to a variable.
Note that mere stored procs or user-defined-functions are insufficient, as they can’t handle all snippets (like declaring variables which are used in the calling function), or they have awful performance in the where clause.
We can use a technology “SqlCmds” to accomplish this. (http://msdn.microsoft.com/en-us/library/aa833281.aspx).
How to enable Sql Commands in SqlStudio:
http://msdn.microsoft.com/en-us/library/ms174187.aspx
- Single query window – “On the Query menu, click SQLCMD Mode.”
- For all windows – “To turn SQLCMD scripting on by default, on the Tools menu select Options, expand Query Execution, and SQL Server, click the General page, and then check the By default open new queries in SQLCMD Mode box.”
How to enable Sql Commands in Visual Studio
This requires the database edition of Visual Studio. Click the allow "SqlCmd" button on the tool bar.
Basic variable test
--set variable, and then use it - use the ":setvar" command
:setvar SomeTable TestCodeGen
select * from $(SomeTable)
-- environmental variables too!
select '$(COMPUTERNAME)' --returns my comp name (like 'TimStall2')
This means we could have an external script set the environmental variables (like the PrimaryDataBase), and then easily re-run those in the SQL Editor. Note that you can use the free tool SetX.exe to set environmental variables.
File Include – Basic (use the “:r” command)
--File 1 (var_def.inc):
:setvar PrimaryDB MyDatabase70
--File 2:
:r C:\Development\var_def.inc
select * from $(PrimaryDB).MySchema.TestCodeGen
For example, we could have a “header” file that includes a bunch of variable definitions (like all the PrimaryDB, ReportDB, etc…), and then include it wherever needed. Or, we could include any other SQL snippet. For example, we could use this to effectively make private functions (instead of only have global functions) that are encapsulated to a single stored proc.
File Include – avoid function in a where clause
--File 1 (myProc_func1.sql):
--some reusable snippet (note how is uses the variable '@myNum")
co = '1234' or NumberInteger > @myNum
--File 2:
declare @myNum integer
select @myNum = 10
select * from TestCodeGen
where
:r C:\Development\myProc_func1.sql
and LastChangedBy < GetDate()
Summary
One catch to all of this is that if you have your own database installation code via ADO.Net, you need to manually parse it yourself. However, that should be easy enough to do given the strict syntax of the SqlCmds.
Note that this is substituted “at compile time”. If you run the SQL Profiler, you won’t see the “:setvar” or “:r”, but rather the content already parsed. These techniques could be used to help refactor SQL code, just like similar techniques help refactor the code in other languages.
Tuesday, February 17, 2009
The different between Count, Length, and Index
When dealing with arrays and collections (like List
- Count - refers to collections. This simply gets the number of items in the collection.
- Length - refers to arrays. to quote: "Gets a 32-bit integer that represents the total number of elements in all the dimensions of the Array." (emphasis added). For a 1-d array, Count and Length seem similar. But for multi-dimensional arrays, the difference becomes apparent. A 3x2 array will have a length of 6. Because an array is allocate up front (as opposed to a collection that can grow or shrink), this conceptually makes sense. Length for an array doesn't change after declaration; Count for a List does (as you add or remove items).
- Index - used by arrays, and some collections (like List
), to indicate a specific item in the array or collection. Whereas Count and Length are 1-based properties, Index is a 0-based indexer.
This code snippet shows these in action:
[TestMethod]
public void TestMethod1()
{
//Length --> total number of items in the array
// acts like "Count" for a 1-d array
string[] astr = new string[]{"a","b","c"};
Assert.AreEqual(3, astr.Length);
// but very different for a 2-d array
string[,] astr2 = new string[2, 3];
Assert.AreEqual(6, astr2.Length); //Length = 2 * 3
//Count --> 1-based
List<string> lstr = new List<string>();
lstr.Add("a");
lstr.Add("b");
Assert.AreEqual(2, lstr.Count);
//Index --> 0-based
Assert.AreEqual("a", astr[0]);
Assert.AreEqual("b", lstr[1]);
}