Category Archives: Work

WCF HTTP Preview

Check out http://wcf.codeplex.com/, and let us know what you think.

We’ve been hard at work on the next version of WCF, and today at PDC Glenn unveiled the details of those investments. We’ve made a number of usability and functional improvements, including first-class integration with Async.NET and a comprehensive set of enhancements to WCF HTTP. We’ve posted a preview of the HTTP enhancements at http://wcf.codeplex.com, and eagerly await your feedback. More to come…

Back in the Office

One year later, I’m back from sabbatical and in my office (which has been moved to building 18). It’s a bit surreal to be back, though fun to be catching up on the past year of developments and reconnecting with our plans for WF and WCF. I’m looking forward to reengaging with our customers as well. More soon….

errorspotting.com

Inspired by some of the frustrating experiences we’ve had with technology this year, and to add to our ever-growing DNS footprint, Lauren and I have launched a new blog: errorspotting.com. Our goal is to highlight egregious error messages and experiences in the hope of inspiring (and humiliating) developers and designers to create better user experiences when things go wrong.

We have posted a few items so far, and are eager to include reader contributions to help in our quest to reduce the pain and frustration of users around the world.

ArgumentException: The string must be at least XXX characters long

I hit this obtuse exception the other day. The stack had System.Configuration code on it, which is the only way I managed to track it down to a StringValidator attribute. A few things that would have been helpful:

  1. Having the name of the culprit in the exception string (i.e. The string ‘foo’ must be at least 24 characters long.)
  2. Including the configuration element of which string ‘foo’ is a property of (i.e. The string ‘foo’ must be at least 24 characters long to be used for property ‘bar’ on element ‘baz’.)

Turns out that this was not actually a .config file error. After subclassing StringValidator and creating a ConfigurationValidatorAttribute to bridge into the declarative system, I discovered that the exception was being thrown while validating the default value.

I had naively thought that if you have a required ConfigurationProperty, then you do not need to setup a default value. I was wrong. I discovered that this is a known bug in the .Net Configuration validation framework that has been resolved “By Design”.

I completely understand why they want to run the validators on default values, but the framework really should check if a property is required and suppress default value validation in that case. As it is, the default value is never used, and the framework properly throws an exception if the required property isn’t explicitly set by the user.

As a result, the following is the “correct” way to have a required property that works with the config validation framework:

[ConfigurationProperty(namePropertyName, IsRequired = true,
   // We need to set a default value for our string validator to work 
  
DefaultValue = "dummy")] 
[StringValidator(MinLength = 1)]
public string Name { … }

Error 1001. The specified service has been marked for deletion

Sometimes I think I should run a signspotting campaign for error messages. In this particular case, the error happens when trying to install or uninstall a Windows service.

Since there was nothing actionable in the error message (sigh), it was off to the web. On MSDN, the only “fix” was to reboot your machine. Boo. Fortunately after digging deeper it turns out that all you really need to do is close services.msc if it’s open.

Given that this is a fairly common situation for services development, hopefully this post will save a few reboots. And maybe the next version of Windows will say something to the effect of “service was unable to install/uninstall because services.msc is open, please close the control panel and retry your installation.”

Viewing TFS 2008 Installation Guide on Windows Server

Turns out that installing TFS 2008 is not for the faint of heart. The installation guide provides some important information. However, on my Windows Server box, the CHM file wasn’t viewable due to the default security settings. Fortunately a quick web search turned up Tim’s post (in brief, right click Properties->Unblock Active Content on the chm file). One stumbling block down, onto the rest of the install…..

Adding “Log on as a Service” permission to a Server 2003 account

Today I setup a custom service account on a WinServer 2003 box. I expected that it would be simple enough to enable “log on as a service” through the user properties dialog. Of course life is never that easy. Since the box was a domain controller, it turns out I needed to make this change via group policy.

It was one of those cases where I didn’t have quite the correct way of asking Bing/Google for the answer. If I had, then it would have led me to some very crisp instructions on technet (account “log on as service” gives this as the third hit on Bing/first hit on Google…<sigh>).

Threading in WF 4

A number of customers have asked about the threading model used for WF 4. In brief, our extensibility for threading in the WF Runtime is based on System.Threading.SynchronizationContext.

When a execution is kicked off (indirectly through ActivityRuntime.Run), we will first call SynchronizationContext.OperationStarted(). Next we will call SynchronizationContext.Post() to get on a “workflow” thread.

We will then execute any pending work items from our internal scheduler queue. It is possible that more work items will be scheduled (through context.ResumeBookmark, context.ScheduleActivity or activity completion). In that case, we will continue to execute those work items as well. Execution will remain on the “workflow thread” until we either go idle (no more work items), or the runtime is explicitly paused by the host through ActivityRuntime.RequestPause (which is what’s called underneath Unload() for example). When this happens, we will call SynchronizationContext.OperationCompleted().

How you configure a SynchronizationContext depends on the host construct that you are using.

  1. For WorkflowServiceHost, we will use the the value of SynchronizationContext.Current at the time of workflowServiceHost.Open (unless UseSynchronizationContext is set to false). This is consistent with the rest of WCF.
  2. WorkflowInvoker.Invoke/BeginInvoke has overloads where you can explicitly provide a SynchronizationContext for us to use
  3. WorkflowInvoker.InvokeAsync will use the value of SynchronizationContext.Current for consistency with the Whidbey async pattern
  4. WorkflowInstance has a constructor overload which allows you to explicitly provide a SynchronizationContext for us to use

If no SynchronizationContext is provided by the host, we will use an internal WF default SynchronizationContext. The WF default SynchronizationContext uses IO completion ports under the hood to implement Post().

Setting up SQL Persistence for WF4 Beta 1

A few customers have hit a speed bump when trying to setup persistence with WF4 Beta1. We have multiple sql scripts included (for 3.5 persistence and 4.0 persistence). The problem is that depending on your WF application model in Beta1 you have to execute different scripts (we’ve fixed this in Beta2).

For WorkflowServiceHost usage, use these SQL scripts:

  • C:WindowsMicrosoft.NETFrameworkv4.0.20408SQLenSqlPersistenceProviderSchema40.sql
  • C:WindowsMicrosoft.NETFrameworkv4.0.20408SQLenSqlPersistenceProviderLogic40.sql

For WorkflowInstance usage, use these SQL scripts (note the lack of “40”):

  • C:WindowsMicrosoft.NETFrameworkv4.0.20408SQLenSqlPersistenceProviderSchema.sql
  • C:WindowsMicrosoft.NETFrameworkv4.0.20408SQLenSqlPersistenceProviderLogic.sql

Also make sure that the connection string in your application matches the database you created.