December 2006 - Posts
As Don Box says, you have to love the web. Don says
For those who don't know, screenscraping is a technique in which a computer program extracts text data from the display output of another program. In other words, your application requests the HTML from a Google search and you transform it into a SOAP message. That's exactly what has been done, and that in about 3 or 4 days or so! Again, you have to love the web.
If you've missed out on everything, Google had a soap service that you could access to get results from a search. The service is still alive, but support is discontinued. They now offer an Ajax search API. This has been the reason for a lot of debate on the internet.
Technorati tags: EvilAPI
Just recently Service Pack 1 was released (Beta!) for Visual Studio 2005. Back then, the Vista update had a link, but it was removed. Miguel blogged that the beta version is online!
This update is required because of the security enhancements to Windows Vista. One of the biggest problems was the debugger, for example attaching the debugger to the new IIS7. Here's info from Microsoft...
During the development of Windows Vista, several key investments were made to vastly improve overall quality, security, and reliability from previous versions of Windows. While we have made tremendous investments in Windows Vista to ensure backwards compatibility, some of the system enhancements, such as User Account Control, changes to the networking stack, and the new graphics model, make Windows Vista behave differently from previous versions of Windows. These investments impact Visual Studio 2005. The Visual Studio 2005 Service Pack 1 Update for Windows Vista Beta addresses areas of Visual Studio impacted by Vista enhancements.
Remember when installing you run it with elevated administrator rights. According to Microsoft you have to have UAC enabled.
Get it here.
Via Tim Sneath I've learned that you can start an elevated command prompt from the Start Menu. Press ctrl-esc to pull up the start menu, type in "cmd". cmd.exe is the command prompt. When it's visible, just press ctrl-shift-enter and it'll start up with elevated administrator rights.
This is very handy for executing iisreset as well, as you need elevated rights for it as well. But also Visual Studio 2005 and other applications can be started that way.
Something I really miss however is starting any file, with a right-click, as administrator. For example for my Visual Studio 2005 solutions I would've loved this functionality. Perhaps it can be achieved by some registry hacks. I'd like to know!
Technorati tags: Windows Vista
Download code & sql scripts here
I got a question today about setting the isolationlevel on a transaction to ReadUncommitted. The question was why the transaction still locked the row it was updating, when isolationlevel is set to ReadUncommitted. It was expected that using ReadUncommitted on the transaction allowed other requests (on a different connection) to read the data, even when it wasn't committed. When we take a look at the SQL Server 2005 Books Online you can read the following:
Specifies that statements can read rows that have been modified by other transactions but not yet committed.
When you read this real fast, you might think that statements can read rows that have been modified by transactions, but not yet committed. But it doesn't say that. It says, "rows that have been modified by other transactions..." So what's the difference? Let's look at it through code.
I've setup a simple table with two columns. The table is called [MyTable] with a primary key called [MyTableId] of type integer. Also a column called [value] of type varchar(50). I've added five rows which you can see on the left.
I've got some examples in which I'll create a transaction, update the 5th row with a new value. In every example I've added wait statements so that another connection can try to read the changed value of this 5th row. It'll either fail because of a lock, or not if done correctly.
The following T-SQL code will setup the transaction's isolation level to Read Uncommitted (line 1), start a new transaction (line 4) and try to update the table (lines 6-8). It than waits for 15 seconds (line 10) and finally rollback the transaction (line 12). Within these 15 seconds you'll have time to execute another query in another query-window. For example "select * from MyTable where MyTableId = 5". You'll notice it'll lock-up for 15 seconds.
1 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
4 BEGIN TRANSACTION
6 UPDATE MyTable
7 SET Value = 'changed'
8 WHERE MyTableId = 5
10 WAITFOR DELAY '00:00:15'
12 ROLLBACK TRANSACTION
Why is this happening when IsolationLevel is set to Read Uncommitted? The answer lies in the single word "other", as stated above. When setting IsolationLevel to Read Uncommitted, you can read rows from another transaction. But you'll have to set the isolation level on this connection. On the connection you're reading with! For this you don't need a new transaction, but you do need to copy line 1 from the T-SQL code above.
Or you can use a table hint. "Hint' is actually a misnomer, because it's not a hint. It overrules the currently set isolation level. In our case, we could use the table hint as follows.
FROM MyTable WITH (READUNCOMMITTED)
WHERE MyTableId = 5
We can achieve the same result(s) in .NET. I'm written my examples using .NET 2.0 but I'm (pretty) sure the first example can be used in .NET 1.x as well.
1 const string connectionString = "server=dennisvista;database=laboratory;integrated security=sspi;";
3 const string query1 = "update mytable set value = 'changed' where myTableId = 5";
4 const string query2 = "select value from myTable where myTableId = 5";
5 const string query3 = "select value from myTable with (readuncommitted) where myTableId = 5";
6 const string setIsolationLevel = "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED";
8 SqlConnection con1 = new SqlConnection();
9 SqlConnection con2 = new SqlConnection();
11 con1.ConnectionString = connectionString;
12 con2.ConnectionString = connectionString;
17 SqlTransaction trans = con1.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted);
19 SqlCommand cmd1 = new SqlCommand();
20 cmd1.Connection = con1;
21 cmd1.Transaction = trans;
22 cmd1.CommandText = query1;
24 SqlCommand cmd2 = new SqlCommand();
25 cmd2.Connection = con2;
26 cmd2.CommandText = query2;
30 // Uncomment the following line to set the ReadUncommited isolation level
31 // new SqlCommand(setIsolationLevel, con2).ExecuteNonQuery();
33 // Timeout will occur because of the lock
34 string value = cmd2.ExecuteScalar().ToString();
We've got two connections set up. On line 17, we set the IsolationLevel to ReadUncommitted. Again this doesn't make sense for the result we want to achieve at line 34. We execute query1 on line 28, which will create a transactional lock on line 34.
At line 31 however you can see in a single line that we set the IsolationLevel to Read Uncommitted, on the second connection! So if you uncomment line 31, you'll actually read the data that line 28 is trying to update. Of course it's not yet committed, but that's what Read Uncommitted does. In this example we're not using query3, but it would produce the same result as setting the isolation level. The difference is with query3 we're not setting Read Uncommitted on the entire connection. Instead we're only using it with a single query.
So we finally get to using System.Transactions. In the example below we're using the exact same queries as above. You can see we wrap the TransactionScope around both connections. But we first set up the IsolationLevel in line 2, then pass this to the TransactionScope constructor on line 4. Now both connections automatically enlist in our transaction and also both have the IsolationLevel set to Read Uncommitted.
1 TransactionOptions transOptions = new TransactionOptions();
2 transOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted;
4 using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew, transOptions))
6 using (SqlConnection con1 = new SqlConnection(connectionString))
9 SqlCommand cmd = new SqlCommand(query1, con1);
13 using (SqlConnection con2 = new SqlConnection(connectionString))
17 SqlCommand cmd = new SqlCommand(query2, con2);
18 string value = cmd.ExecuteScalar().ToString();
The problem here is however that we'll automatically get bumped up to a distributed transaction. So make sure the MSDTC service is running.
Now you know how you can read uncommitted data that's being updated in other transactions. Be sure to know however that this is called a "dirty read". You're reading data that in 99% of the time is data you don't want. It's not being updated for nothing! The person who asked me the question actually had a valid reason to choose this, although the initial design of the application might not be the best. But it wasn't his, so he wasn't to blame.
Sahil Malik once made a weblog post about why the heck (old weblog) we would want to use ReadUncommitted. He couldn't think of a single reason to use it. I now know one reason, but I still agree with him. I'm sorry if I wasted your time with this long weblog post, with a final conclusion that you shouldn't use ReadUncommitted. ;-)
Table of contents
- An introduction
- Unit Testing
- Promotable Enlistment
- What to choose?
I was reading Steve Eichert's weblog when he mentioned Mozy, an online backup service. For $4.95 per month you'll get 50GB of backup storage. Even better, you can get 2GB for free! If you're interested, be sure to check the following link:
Mozy Free 2GB backup storage + 256MB extra!!!
When you use me as a referral, we both get 256MB extra storage!
Be sure to read the website carefully. Not because of the small print, but because of the extremely funny jokes these guys make. You just have to love them! For example, they advertise on their site with 1GB free extra storage space. With every new user that's using you as a referral, you'll get 256MB extra. "That's 1GB of free space for every four people! (We have powerful computers here that can do that sort of math.)"
On the weblog, you can read an article about defragmenting your harddrive.
Let's say you are trying to retrieve some data from your computer - for example, a segment of text that reads "Help me, Obi-Wan Kenobi; you're my only hope." And let's say you want to get that data very, very quickly.
If your vital message that you needed to get to was on your disk, it would take you lots, lots longer than it would take if it is in RAM or in your CPU cache. Of course, 12 million nanoseconds really isn't that long - but the problem is that it can add up, and the rebel alliance really needs that data.
Laughing out loud here! :-)
And be sure to check out their probability is fun weblog entry.
I don't know if you can find them, but I have no idea how to get to the login page and/or register account page via some link, on weblogs.asp.net and blogs.msdn.com. A lot of blogs have anonymous comments turned off, therefor you might want to register or login. Another reason is subscribing to new comment, so you'll get an email when a new one is added.
Luckily they're using Community Server, so those locations are the same everywhere. If you want to know, these are the locations.
- Create a new account
- Create a new account
And suddenly it's there...
There are over 70 improvements for common development scenarios, including:
- New processor support (e.g., Core Duo) for code generation and profiling
- Performance and scale improvements in Team Foundation Server
- Team Foundation Server integration with Excel 2007 and Project 2007
- Tool support for occasionally connected devices and SQL Server Compact Edition
- Additional support for project file based Web applications
- Windows Embedded 6.0 platform and tools support
On Windows Vista, you'll have to install Service Pack 1 and then install the SP1 Update for Windows Vista. Remember that this is a beta.
Unfortunately the update for Vista version is still not yet available! The official version should be released Q1 2007, but I need it now. So I'd like to install the vista update beta version, if it'll come available.
I love (!!!!) the new Powerpoint 2007 presenter view functionality! I absolutely love it!
Normally you'd have the full slide on both the beamer and your own screen. With Powerpoint 2007 you can set the presentation on your second monitor, as seen on the right. In my case, this is the beamer. Then check the presenter view option, also shown on the right. Now start the slideshow.
It will now show the full slide on the beamer, but will give you a special "presenter view" (hence the name ;-). You'll get to see the current slide on your workstation (laptop in my case) and your notes on the right. At the bottom of the screen you'll get to see a bunch of slides that'll come next.
Of course for a presenter, this is a great enhancement to Powerpoint. It's a Powerpoint feature, so it doesn't matter if you're running XP, Vista or another Windows version. It's much simpler though if you're running Vista, because it'll ask you if you want to extend your desktop or just 'clone' the desktop to the beamer. In Windows XP you'll have to set this up in your display properties. Select the second monitor and choose to extend the desktop. Again, don't forget to set the second monitor to show the presentation on.
view of desktop when presenting
I'm subscribed to the MSDN Subscriber downloads RSS feed, but for some reason it wasn't updated until this morning. Some interesting stuff that's there to download:
- Windows Vista (multi-language)
- Office 2007 Professional (multi-language)
- Office 2007 Ultimate
- Office Professional Plus 2007
- Visual Studio Team System for Database Professionals
(I guess this version isn't for developers, just for database professionals)
- Office Language Pack 2007
(No more need for Mike's Office 2003 proofing tools ;)
...and a lot more products with multi-language support, like Office SharePoint Designer 2007.
I talked to my colleague Alex Thissen recently about the changes in asynchronous invocation of ASP.NET 2.0 webservices. On the web there are a multitude of examples about the old way, but not so many on the new way. But after figuring out what the new way was, I started asking myself why they changed it. Probably for the benefit of readability and ease of use. But still, it's not the first time I questioned why and how.
After discussing this with Alex, he wrote a weblog post on the ASP.NET 2.0 async invocation pattern and showed the old and new way of doing things. In this weblog post I wanted to show the subtle difference between the VB.NET and C# versions.
In Visual Basic.NET 2.0
Dim proxy As New HelloWorldService.Service()
AddHandler proxy.HelloWorldCompleted, AddressOf HelloWorldCompleted
Console.WriteLine("Press any key to exit...")
Public Sub HelloWorldCompleted(ByVal sender As Object, ByVal args As HelloWorldService.HelloWorldCompletedEventArgs)
In C# 2.0
static void Main(string args)
HelloWorldService.Service proxy = new HelloWorldService.Service();
proxy.HelloWorldCompleted += new HelloWorldService.HelloWorldCompletedEventHandler(proxy_HelloWorldCompleted);
Console.WriteLine("Press any key to continue...");
static void proxy_HelloWorldCompleted(object sender, HelloWorldService.HelloWorldCompletedEventArgs e)
Woohoo!!! Am I the first in The Netherlands to have one?! :)
Recently I've installed a search provider for IE7 on BloggingAbout.NET. This means that on every page here you should be able to search this site using the search box in the upper-right corner of your IE7 browser. You can also install it into IE7 and use it while you're not at our community site.
Although I had already figured this out via wikipedia.org, who also use this... You can view how it's done on this site.
Ranting coming up, you might want to skip ;-)
This is not actually a Vista problem, but a Windows problem. Why is the My Documents (or in Vista: Documents) folder so abused? Just take a look at what's in mine and note that I'm not actually saving my documents in there.
Why are all these files/folders in there? Isn't that an "Application Data" folder somewhere? Why do I feel I need a "My actual documents" folder in there? Maybe I need a little tool that transfer everything that's not actually mine, into some other folder.
A while ago I saw this decision chart to help choose a WCF default binding. Unfortunately I cannot remember where it came from. The problem I had with it was that you could only reach wsHttpBinding if you had to use interop. But you might need to use HTTP for a transport. Also the local option came too soon, where answering yes ruled out MSQM and P2P. So I had to change the original chart a bit. If there are any errors, please make a suggestion in the comments and I'll try to fix the chart.
Class-A logo in there because it's from our training material. You can use the chart for whatever you like though.
Almost a year ago, January 26, I tried to start a short list of links that I found interesting, and called it Newsflash. Unfortunately, not much came from it, until now. Here's #2 ;-)
- CardSpace/InfoCard for .NET 1.1
It's really nice that in the future, dasBlog supports CardSpace under .NET 1.1! Garret Serack, Program Manager on the Federated Identity Team (Cardspace) build this to support CardSpace for dasBlog users who don't have the luxury of .NET 3.0. I wonder if it's also working under .NET 2.0, as all/most assemblies should run under 2.0.
- Provider Pattern: A practical guide to decoupling .NET 2.0 applications
My friend Miguel has written a short but very practical introduction into the Provider Pattern that's widely used throughout ASP.NET. I've never seen such short but good explanation on how the Provider Pattern works. I'd suggest he'd do this more often and perhaps workout an example of the pattern.
- C# 3.0 for mere mortals, part 5: Lambda expressions
If you haven't seen Alex Thissen his article series on C# 3.0 for mere mortals, be sure to check them out. He's a star in explaining things, so if you don't understand what he's saying about Lambda expressions, you might think again about being a developer. Just kidding of course. But I do believe after a lot of hobbyists started doing .NET, developing can become an art again with every new version of .NET.