Saturday, October 13, 2007
Deadlocking / Aborting Workflows with Tracking and Persistence
UPDATE: Thanks to a very quick response from the product team on this on connect.microsoft.com... It turns out the workflow is not deadlocking, but is aborting. And it is not completely silent about it, you just have to be listening to the WorkflowAborted event on the runtime.
I've been bit a couple of times by this one, so I thought I would record it here as much for my own records as for others who might get similarly stuck.
Tracking and Persistence are two of the powerful capabilities that Windows Workflow Foundation (WF) offers that work right out of the box. You can easily enable them with code like the following:
12 [STAThread]
13 static void Main()
14 {
15 using (WorkflowRuntime runtime = new WorkflowRuntime())
16 {
17 SqlWorkflowPersistenceService persistence =
18 new SqlWorkflowPersistenceService(persistConnString,true,
19 TimeSpan.MaxValue,TimeSpan.FromMinutes(1));
20 runtime.AddService(persistence);
21 SqlTrackingService tracking = new SqlTrackingService(trackConnString);
22 runtime.AddService(tracking);
23 runtime.StartRuntime();
24 ...
25 }
26 }
Tracking allows you to capture lifecycle events of your workflows and activities to a provider (SQL Server persistent store with the built in provider) for operations management monitoring or diagnostic purposes. You can even use tracking events to drive some of your application logic, such as knowing when particular workflows have completed.
Persistence is even more powerful. With persistence enabled, when workflows go idle (waiting on an external event or timer), the workflow runtime can persist the workflow (serialize the workflow object and all of its contained activities state) and stick it in a persistent store (SQL Server with the built in provider). Then when the event occurs, the runtime can wake the workflow back up and turn it back into objects and get it running again. This keeps you from consuming resources on the server for long-running workflows that are just waiting for something that might take hours, days, weeks, or months. It also allows you to scale out the execution of your workflows to multiple servers in a farm, because another (less busy) server can pick up the workflow when it is ready to run instead of the one that was originally running it. You can also prevent this from happening with a process lock if that makes sense for your scenario. Persistence also allows your running workflows to survive across server restarts. All amazing capabilities that you get for free from the workflow runtime.
Both tracking and persistence can also be enabled through your config file as well.
So where is the gotcha? Tracking and Persistence work perfectly fine with one another, normally. However, you can find yourself with your workflows deadlocking indefinitely if you turn them both on, and the cure may not be very apparent unless you really understand how they are working under the covers. OK, even if you understand that, you really have to think it through to understand the cause.
First, the short answer: If you find that your workflows are hanging or deadlocking when they go idle with both persistence and tracking turned on, check to make sure your Distributed Transaction Coordinator (DTC) service is running.
The explanation: If you enable tracking and persistence with code like shown above, both services write their data to the database as part of a transaction. Depending on whether you put them in the same database and depending on which workflow commit batch service (whole separate topic there) you use, the writes to your tracking and persistence stores may or may not use the same connection to talk to the database (obviously if separate databases, they will not). However, they do get wrapped up into a single transaction when a persistence point is hit at the same time as a tracking point (such as when an workflow goes idle). So if the DTC is not running, the transaction cannot promote to a DTC transaction and the workflow ends up deadlocking. Getting the DTC service running fixes the problem.
Normally DTC should be running on a machine with SQL Server running anyway, but I have had it happen on more than one machine where it was not running and had this problem.
The workflow runtime should really be throwing an exception or timing out after a reasonable time if it can't promote the transaction, but instead it just silently deadlocks.
Hopefully if you have this problem, you will find this post through your search engine of your choice and your problem will be solved.
Monday, October 08, 2007
Exposing WPF Windows or Windows Forms as WCF Services
Why would you want to do that, you might ask? The scenarios are not many, but picture a window's whose whole purpose in life is to display data pumped into it by other processes. Maybe you have heard of such a thing.... one of these you might have heard of is called Performance Monitor (although that of course is not written in WCF). Or you could envision a manufacturing line monitoring application where the droid controller applications constantly send status, position, count, etc. information to the monitor app.
There is are some subtle tricks to doing this that you should be aware of if you head down this path.
First issue: Concurrency
By default, WCF answers incoming service calls on threads from the thread pool. There is a hard rule in windows programming that thou shalt not make modifications to the UI from a thread other than the UI thread. Windows Forms did not really enforce this, but stood the chance of crashing at unpredictable times (as with all concurrency problems) if you ignored the rule. VS 2005 and beyond help us out by throwing an InvalidOperationException when in debug mode if it detects that you are violating this rule. WPF makes it more rigorous by baking it into the DispatcherObject from when all UI elements derive so that any attempt to access a member of a DispatcherObject derived class from a non UI thread (if that object has thread affinity) will immediately throw an exception.
The good news here is that WCF also by default detects thread affinity when you open your service host, and if it sees that the calling thread has a SynchronizationContext (as both Windows Forms and WPF do), it holds a ref to that object so it can use it to automatically marshal the incoming calls to the right (UI) thread. This is driven by the UseSynchronizationContext property of the ServiceBehavior, which is true by default.
So basically if you do nothing in a forms app, the right thing happens and all incoming calls to the service will be marshalled to the UI thread, so those calls can be safely dispatched to the window, and you can update the UI from within the service method of the call chain that ensues.
Note that you can still run into concurrency issues if you call out from the window on the UI thread and that call chain comes back into the thread as an incoming service call or callback. Then the incoming call tries to marshal over to the UI thread, but that thread is blocked until the outgoing service call completes, which can't happen because it is waiting for the incoming call to complete as part of its call chain... deadlock. There are a number of ways to break that deadly embrace, but that is a separate post. The good news again... WCF protects you better than normal .NET multithreading because calls timeout. So you will only be deadlocked until the outgoing call times out (60 seconds by default), then an exception will ensue.
Second Issue: Instancing
Because in many situations you don't have to explicitly worry about the instancing modes of WCF, you might not think about this when setting up your window to expose it as a service. For example, you might write try to write your code like the following:
1 public partial class Window1 : Window, ITalkToPeer
2 {
3 ServiceHost m_host = new ServiceHost(typeof(Window1));
4 public Window1()
5 {
6 InitializeComponent();
7 m_host.Open();
8 }
9
10 // Service method
11 public void SendMessage(string msg)
12 {
13 m_PeerMessageListBox.Items.Add(msg);
14 }
15
16 private void OnWindowClosed(object sender, EventArgs e)
17 {
18 m_host.Close();
19 }
20 }
In the code above, ITalkToPeer is the service contract and defines a single member SendMessage, which is implemented by the window as the service.
So what is wrong with this code? Well, if you put it together and try to run it, you will not see any messages flowing into the ListBox when clients make the calls.
If you understand the instancing modes of WCF, you can fairly quickly piece together why. Where is the data going? it won't even matter if you make all the calls from a single client through the same proxy or if multiple clients are calling. What's the deal?
By default, the instancing mode (ServiceBehavior.InstanceContextMode to be specific) of a WCF service is Session. That means if the same client calls through the same proxy instance, the calls will all get dispatched to the same instance of the service implementation class (which is Window1 in our example). The problem is that WCF is in charge of creating the instances, and it does so when the calls come into the service. So even though our service hosting environment is set up from within our single window instance, we just told it what type to create through the ServiceHost constructor, we didn't give it a reference to the instance.
The fix is quite simple once this realization is made. We just have to change our instancing mode to Single (meaning singleton), and use the overloaded constructor of ServiceHost which allows us to pass in a reference to a pre-constructed singleton instance. The fixed code is shown below. The problem was that a separate window instance was being created (but not shown) for the incoming calls, so the data was just going into the object model of that non-visible window instance instead of being shown in the main window you were expecting it to.
1 [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
2 public partial class Window1 : Window, ITalkToPeer
3 {
4 ServiceHost m_host;
5 public Window1()
6 {
7 InitializeComponent();
8 m_host = new ServiceHost(this);
9 m_host.Open();
10 }
11
12 public void SendMessage(string msg)
13 {
14 m_PeerMessageListBox.Items.Add(msg);
15 }
16
17 private void OnWindowClosed(object sender, EventArgs e)
18 {
19 m_host.Close();
20 }
21 }
Sunday, October 07, 2007
New CodeRush 2.5.4 WCF Templates
Those of you who have worked with me or have seen me present know I am a big fan of CodeRush and Refactor Pro, from DevExpress. In fact, if you get me talking about it, you can't shut me up. To sum all my fan boy slobbering praise down to what you really need to know if you have never heard of it or checked it out, CodeRush is a tool that:
- Is like a combination of Visual Studio Code Snippets and Intellisense, both on super-crazed, interplanetary steroids
- Adds code visualization, navigation, and clipboard tools that will also make you way more productive while pounding out code
- Bottom line: it is a tool that even if used to only 10% of its capabilities, will pay for itself within a week or two in making you more productive
- Comes with Refactor Pro, another essential tool to make it much faster and safer to refactor your code to make it clean
Anyway, last week they released a small update (2.5.4) which includes some awesome new templates for WCF coding.
If you have done much WCF coding, you'll know that WCF coding is more about adding attributes and config file entries than it is about writing imperative code, at least for the WCF specific stuff. For examples, defining a service contract, operation contracts, service behaviors, transaction flow, etc. is all done with attributes in code. But there are also a few common constructs you'll write in code, such as creating an instance of ServiceHost or creating a client-side proxy class by hand because the code that VS and svcutil generates is way more verbose than it needs to be.
Then there is the config file... this is where you will spend a lot of your time, and there is nothing worse than writing a lot of angle brackets by hand (even with intellisense helping) just to get some structure in place for the values you really need to provide. The SvcConfigEditor helps some here, but it sometimes does a little too much magic behind the scenes for you, so knowing exactly what is being set means digging into the config file yourself.
This is where the CodeRush templates come in. With a little collaboration with an unnamed individual at IDesign, they have come up with a great set of templates for all the most common code chunks you will add to your WCF services and clients.
For example, instead of having to type 17 characters to decorate an interface with a ServiceContract attribute (see... it physically hurt me to have to actually type all those characters just now, knowing CodeRush could do most of that for me if I were just in VS), I can type 3 plus the space bar - [sc and I have [ServiceContract()] in my code, with the focus inside the parens in case I want to set some properties, and enter jumps me to the end of line in case I don't. Maybe those extra 14 characters don't sound like a lot to you, but add them up over and over and you will get the idea. Here is a tool that can make you 82% faster immediately. OK, well, intellisense saves you some of that, and that assumes you never have to think when coding. I think only Mark Miller, the architect of CodeRush, is that good. But still, trust me, you will feel the time savings in the form of keystroke savings very quickly as you adopt CodeRush.
Even more important, consider a service host you are adding the first service to. To get that service hosted, you need a chunk of code like the following in your config file: <system.serviceModel> <services> <service name="MyNamespace.MyService"> <host> <baseAddresses> <add baseAddress="http://localhost:2112/"/> </baseAddresses> </host> <endpoint address="MyService" binding="wsHttpBinding" contract="MyNamespace.IMyService" /> </service> </services> </system.serviceModel>
There are over 200 characters of pure structure in there. I can write this now with one character - s and a space bar hit. Placeholders are put on the items I do need to customize (service name, addresses, binding, and contract) so it is very quick to move from one to another by overtyping, enter, overtype, enter, etc.
Lots of great templates along these lines. For the XML config file entries, you can see the top level ones in the template browser:
These are all backed by stuff hiding in that System folder that let you hit all the most common combinations such as bt for a TCP binding, bh for an HTTP binding, etc.
Mark even added some new smarts for detecting parent elements so it will check if the binding has an enclosing <bindings> parent, and will only add it if not.
Code wise the two there for now are to add a service host block: using (ServiceHost host = new ServiceHost(typeof(ApplicationService))) { host.Open(); Console.WriteLine("Press Enter to Exit..."); Console.ReadLine(); }
And a "hand coded" proxy class for a client: public class MyServiceProxy : ClientBase<IMyService>, IMyService { public MyServiceProxy() { } public MyServiceProxy(string endpointName) : base(endpointName) { } }
As long as you have the interface type in scope, you can then just implement the interface, add the calls through the base class Channel and you have a lean, clean proxy in about 30-60 seconds, usually faster than you can get a verbose messy one through Add Service Reference or svcutil.
Anyway, if you are a WCF programmer and using CodeRush, check out the new templates under the WCF categories in C#/VB and XML code types. If you are a WCF programmer and have not considered CodeRush, maybe you should now.
Thursday, October 04, 2007
NoVA Code Camp Time Again - Speakers Wanted!
We are gearing up for another code camp in the DC/Northern Virginia area. It will be held at the Microsoft Reston training facility on Nov 17th. We have a great set of tracks lined up, and now we just need to fill them with all the brilliant speakers in the area. So if you are willing to come share your expertise with your fellow developers in the area, please lend a hand. Jeff Schoolcraft has a nice description of each of the tracks and what we are looking for here. You can find the full details on the code camp here. You'll need to register and login to submit your abstracts. Thanks and hope to see you there!
Thursday, September 13, 2007
.NET 3.5 Roadshow Demos
My colleagues and I from IDesign are currently hitting 6 cities across the US over this week and next (Ft Lauderdale, Atlanta, and Dallas this week, Denver, Minneapolis, and Boston next week) showcasing .NET 3.5 technologies. I'm giving the sessions on WPF and WF. For those who attended: thanks for being a great audience! You can grab the demos here.
Saturday, July 28, 2007
Visual Studio 2008 WPF (Cider) Designer - First Impressions
Beta 2 is finally here. Got it installed last night and of course one of the first things I wanted to play with is the WPF designer to see how far it had come along since Beta 1 and the Nov CTP tools for VS 2005. Positives: - The designer surface itself has come a long way and the snap lines, margin guides, and other adornments to help get elements positioned within the UI and visualize what underlying layout properties have been set looks really nice.
- There is a zoom control that makes it really easy to zoom in and out with smooth scaling to focus on the parts of the UI you are working on as a nice alternative to scrolling.
- They have a great little breadcrumb control at the bottom that lets you see where you are in the element hierarchy and even gives you a pop-up rendering of the other items in the hierarchy as you hover the mouse over them (see below).
- Picks up container locations such as grid cell when you drag and drop a control.
- The properties grid is fixed as far as being able to edit collection properties such as the RowDefinitions and ColumnDefinitions properties of a Grid.
- The XAML editor has improved IntelliSense with icons that help identify different constructs (namespaces, classes, etc when the IntelliSense list is up. The IntelliSense includes listing available namespaces with a clr-namespace construct for types in the project. Once the clr-namespace has been added, custom types show up in the IntelliSense tag list. Nice.
- Common WPF constructs (Window, Page, UserControl) are in the Add > menu from the project.
- Double click to hook up default event! Finally!
 There are still a number of annoying aspects that I sure hope will be worked out by release. Negatives: - Designer load time: Still takes a really long time to load an empty form in the designer.
- Properties grid: No option to sort the properties alphabetical, so you still need to scroll around looking for what category the property you care about might be lurking in. Unfortunately no property search like Blend has.
- XAML Editor: Still does not add closing element tags when you create an open element tag. Very annoying productivity hit wen forced to bang out XAML by hand. Fills everything that is not inside an element tag with a cyan background. There does not appear to be any way to customize this.
Overall, I'm quite pleased with what I see. I think I can finally ditch using the Nov CTP in VS2005 for WPF development! I'll still be using a mix of this and Blend though.
Friday, July 20, 2007
Connecting Apps with WCF: Slides, Demos and Key Concept
I gave a talk on Connecting Applications with WCF to the Space Coast .NET and Orlando .NET User Groups over the last two nights. Had great attendance and questions, thanks to all who attended. If you want the key takeaway from the talk (other than the demos and mechanics of how to connect two applications with WCF and use different bindings and capabilities of WCF), here is the elevator pitch. WCF is a remote communications technology based on SOAP messaging. It is interoperable, powerful, flexible, easy to maintain, and supercedes all the previous remoting technologies in the .NET space: - .NET Remoting
- ASP.NET Web Services
- Enterprise Services (COM+ for .NET)
- MSMQ
Basically, if you are writing a new application or new portion of an application that needs to make remote calls, use WCF and forget all the above exist. WCF gives you a single API for doing remote communications that rolls up all the capabilities of the technologies listed above, allowing you to write your code with most of the details of the remote communications abstracted away. This allows you to change major aspects of your remote communications approach, such as wire level protocol, encoding, security mechanisms, reliability, etc. without touching your programmatic code - you just modify config file settings. If you need to switch from TCP sockets with binary encoding to HTTP SOAP XML messaging, it literally takes about 30 seconds of editing your config files to do so. There are a few fringe cases such as interoperating with a legacy .NET Remoting app, or certain advanced features of MSMQ that you will not be able to do with WCF, but for 98% of the remote communications needs out there, WCF is the choice you should make. If you want the slides and demos I presented, you can grab them here: Slides Demos
Tuesday, July 17, 2007
Bootstrapper Manifest Generator new home
In my ClickOnce book, I talk about David Guyer's excellent tool for creating Bootstrapper manifests for a custom bootstrapper item for your ClickOnce deployed applications. The URL I gave in the book is no longer valid, the BMG has been moved to codeplex at the following address: http://www.codeplex.com/bmg Basically, this tool gives you a nice dialog driven interface on the XML manifest files that make it so you can just check a box in Visual Studio (the Publish tab of project properties, Prerequisites button) to select your custom installers to be included in the bootstrapper setup.exe that is generated by ClickOnce.
Wednesday, June 20, 2007
Data Binding with Windows Forms 2.0 ErrataWPF Window Management and Parenting
I get a lot of questions about what kinds of windows can be created from where in WPF when I give WPF talks. In a talk in Cleveland the other night, there was an attendee who was concerned because he didn't see a way to set a parent window for another window, and thought that is why they did not include an MDI windowing style in WPF. If you want to set up a window ownership model in WPF like you did in Windows Forms, you just need to look at the Owner property, instead of Parent. The behavior is not exactly the same, but a lot of the same concepts apply. If you create a window instance and set its Owner property to a reference to another Window, then when you show the child window it will always be displayed on top of the Owner window. This is typically used when creating an application modal dialog, but it behaves that way even if you show the window with a call to Show vs ShowDialog. The latter just adds the behavior that you cannot select the owner window and interact with it while the dialog is in place. When you call Show on an owned window, the user can still move the window out of the way, click on the owner window and interact with controls in that window. You could do this to create a floating tool palette window for example. The fact that there is not a built-in implementation of MDI doesn't mean the framework doesn't support it, the WPF team just decided to leave that out of scope for the initial (v 3.0) release because very few applications are built from scratch with the MDI model these days. If you really want MDI, you have two choices: - Write it yourself. This would be a little tricky because you would have to detect Window movement and either prevent them from leaving the horizontal or vertical constraints of their owner window's client area, or you would have to deal with how to do clipping of the contained windows, because WPF does not clip by default.
- Adopt Acropolis. This framework is coming out in the Orcas timeframe and provides a modular WPF architecture based on concepts carried over from the Composite UI Application Block and the Smart Client Software Factory. It adds better support for inexperienced programmers to use the framework, adds pre-built components, a great design time interaction, and certain other application level support - such as an MDI application model.
Another window management question that often comes up is to ask whether you can use Windows Forms windows or Windows Forms message boxes within your WPF application. The short answer is - yes you can. You can simply construct a Windows Forms Form class and call show and it will just be another top level window presented by your application. Since Windows Forms message boxes really just make an interop call into the OS to display an OS message box, that is of course supported too. However, WPF has its own MessageBox class, so using Windows Forms MessageBoxes is really only interesting while migrating an existing Windows Forms application to WPF.
|







| August, 2008 (2) |
| July, 2008 (1) |
| June, 2008 (2) |
| May, 2008 (2) |
| April, 2008 (3) |
| February, 2008 (6) |
| January, 2008 (3) |
| December, 2007 (1) |
| November, 2007 (1) |
| October, 2007 (5) |
| September, 2007 (1) |
| July, 2007 (3) |
| June, 2007 (8) |
| April, 2007 (2) |
| March, 2007 (4) |
| February, 2007 (1) |
| December, 2006 (2) |
| November, 2006 (9) |
| October, 2006 (5) |
| September, 2006 (3) |
| August, 2006 (2) |
| July, 2006 (4) |
| June, 2006 (5) |
| May, 2006 (10) |
| April, 2006 (4) |
| March, 2006 (2) |
| February, 2006 (12) |
| January, 2006 (7) |
| December, 2005 (2) |
| November, 2005 (15) |
| October, 2005 (6) |
| September, 2005 (7) |
| August, 2005 (3) |
| July, 2005 (10) |
| June, 2005 (11) |
| May, 2005 (7) |
| April, 2005 (8) |
| March, 2005 (6) |
| February, 2005 (2) |
| January, 2005 (6) |
| December, 2004 (3) |
| November, 2004 (5) |
| October, 2004 (2) |
| September, 2004 (5) |
| August, 2004 (13) |
| July, 2004 (6) |
| June, 2004 (14) |
| May, 2004 (17) |
| April, 2004 (12) |
| March, 2004 (8) |
| February, 2004 (10) |
| January, 2004 (14) |
| December, 2003 (9) |
| November, 2003 (13) |
| October, 2003 (3) |


Sign In
|