<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-22724714</id><updated>2011-04-21T21:28:53.362-07:00</updated><title type='text'>DevMonster</title><subtitle type='html'>.NET 2.0 - ASP.NET VB.NET Sql 2005</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://devmonster.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22724714/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://devmonster.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Quango</name><uri>http://www.blogger.com/profile/14513217379777941843</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-22724714.post-116854942179334260</id><published>2007-01-11T07:36:00.000-08:00</published><updated>2007-01-13T02:01:51.970-08:00</updated><title type='text'>Custom StateActivity in Workflow</title><content type='html'>It's been a while since I've done any blogging. I got so fed up with Workflow Foundation (WF) that I stopped working with the betas. My initial enthusiasm about WF has been heavily tempered by its immense complexity.&lt;br /&gt;&lt;br /&gt;Microsoft has done an excellent job creating nice tools for the GUI design of workflow activities, but the back-end code and plumbing is SO complicated as to make it almost unusable. When you understand some of the complexities of workflow it makes sense what they have done - but knowing why is no help when you have to struggle to integrate WF with anything else.&lt;br /&gt;&lt;br /&gt;This has turned a promising system into something that only experts can really understand and use. This means WF is likely to be a niche product - rather like BizTalk - which isn't widely used because it is so hard to wrap one's head around the complexities. From a business perspective you will need expert staff to develop and write WF plumbing and special cases.. again an issue.&lt;br /&gt;&lt;br /&gt;Take an example. My first project for workflow was a credit control system, which has to be a StateMachine workflow. Some of the states of this workflow are machine-driven (e.g. send an email to the customer), but others are human-assigned tasks (call the customer to chase the debt). As a StateActivity is generic you need some way to distinguish between the two. Secondly, you need a way in the front-end application to show someone which state activities have been assigned to them.&lt;br /&gt;&lt;br /&gt;Subclassing StateActivity was the obvious approach (see previous post) but this I found to be a very painful process. There is little help on how to subclass a StateActivity - it was only after much prolonged testing I found that the Execute method is the point where one can hook into the StateInitialization point, and handling onClose event the hook for StateFinalization. Even so we may have fun and games to come with workflow cancellation etc.&lt;br /&gt;&lt;br /&gt;The second lot of problems comes around dependency properties and events. Lets say I want to allow the developer to run some code just before my custom StateActivity runs - in the same manner as the InitializeTimeoutDuration event does for DelayActivity.  So you define an event and raise this event just before you use the values.&lt;br /&gt;&lt;br /&gt;The problem here is that the developer handling the event has to remember not to write code like this:&lt;br /&gt;    Me.myCustomState.AssignTo = "Person"&lt;br /&gt;&lt;br /&gt;This is discussed in detail here &lt;span style="font-weight: bold;"&gt;http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=670136&amp;SiteID=1&lt;/span&gt; where it shows you have to cast the sender to the activity type first when in a State machine or in some other circumstances. So anyone setting properties has to code:&lt;br /&gt;&lt;br /&gt;    Dim tmp As CustomState = Ctype(sender, CustomState)&lt;br /&gt;    tmp.AssignTo = "Person"&lt;br /&gt;&lt;br /&gt;Yet another pitfall - WF is starting to look like a desert with quicksand dotted about the place, ready to catch you out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22724714-116854942179334260?l=devmonster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devmonster.blogspot.com/feeds/116854942179334260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22724714&amp;postID=116854942179334260' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22724714/posts/default/116854942179334260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22724714/posts/default/116854942179334260'/><link rel='alternate' type='text/html' href='http://devmonster.blogspot.com/2007/01/custom-stateactivity-in-workflow.html' title='Custom StateActivity in Workflow'/><author><name>Quango</name><uri>http://www.blogger.com/profile/14513217379777941843</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22724714.post-115408044520325808</id><published>2006-07-28T02:31:00.000-07:00</published><updated>2006-07-28T02:54:05.220-07:00</updated><title type='text'>Upgrading hard disks in place</title><content type='html'>I have an XP x64 workstation, which I originally built using the motherboard's Sil3512 SATA RAID controller, creating a RAID 0 array on two WD 74gb Raptors.&lt;br /&gt;&lt;br /&gt;This was very fast but of course being RAID 0 was vulnerable to a disk failure taking out the system. I decided to buy two more raptors so that I could either make a RAID0+1 or RAID 5/6 array. The problem was how to migrate, without trashing the XP installation or having to set up another disk to copy the original from?&lt;br /&gt;&lt;br /&gt;Eventually I purchased an &lt;a href="http://www.areca.com.tw/products/html/pcix-sata.htm"&gt;Areca 1120&lt;/a&gt; raid controller which supports RAID 6 and also dynamic volume migration. I tested it offline with four disks - it was quite possible to create a two-disk RAID0 array, copy some data to it, and then add another two disks to the system and migrate to RAID6 dynamically.&lt;br /&gt;&lt;br /&gt;This meant I could copy the original partition onto a RAID0 on the Areca using the two new disks, then destroy the original RAID0 and adde them to the Areca.&lt;br /&gt;&lt;br /&gt;The only problem was that the original RAID0 volume was 138Gb and the new RAID0 volume was slightly smaller, which &lt;a href="http://www.runtime.org/dixml.htm"&gt;DriveImage XML&lt;/a&gt; had a problem with.&lt;br /&gt;&lt;br /&gt;A quick Google and I found the trial edition of &lt;a href="http://www.acronis.com/homecomputing/products/trueimage/"&gt;Acronis TrueImage Home&lt;/a&gt;, which works for 15 days with no restrictions.&lt;br /&gt;&lt;br /&gt;This has an excellent migration tool (which worked under XP x64!), and which reboots the machine, replicates the original partition to the new disk, and copies the MBR. Once I had unhooked my original volume, XP booted with no issues whatsoever. A very impressive tool.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22724714-115408044520325808?l=devmonster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devmonster.blogspot.com/feeds/115408044520325808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22724714&amp;postID=115408044520325808' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22724714/posts/default/115408044520325808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22724714/posts/default/115408044520325808'/><link rel='alternate' type='text/html' href='http://devmonster.blogspot.com/2006/07/upgrading-hard-disks-in-place.html' title='Upgrading hard disks in place'/><author><name>Quango</name><uri>http://www.blogger.com/profile/14513217379777941843</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22724714.post-115399690978183433</id><published>2006-07-27T01:43:00.000-07:00</published><updated>2006-07-27T03:41:50.466-07:00</updated><title type='text'>WinWF - assigning tasks from a state machine</title><content type='html'>After sporadic dalliances with WinWF (or is it just WF?) I think I've solved one problem.&lt;br /&gt;&lt;br /&gt;Often workflow activities need to assign a task to a person, rather than a system. My example is a credit control process that needs a human to call the customer and chase a debt.&lt;br /&gt;&lt;br /&gt;At the client end of the application, we need to be able to see the workflows (and the tasks) that users need to complete. When the task is complete, the task needs to be closed.&lt;br /&gt;&lt;br /&gt;The workflow runtime itsself is not much use in this context - there is no concept of assignment and not much in the way of a query function to locate tasks of certain types, either persisted or in memory.&lt;br /&gt;&lt;br /&gt;My initial approach (with a state machine workflow) was to add StateInitialization and StateFinalization activities to a state that needed action by a human. In these I could set up and then close down a task in my database application. Although this concept worked it did mean I had to be careful to always have both in each state, and it meant setting up each 'user' state manually when encountered.&lt;br /&gt;&lt;br /&gt;Instead I realised that a better way was to create a subclass of &lt;span style="font-style: italic;"&gt;StateActivity&lt;/span&gt;, and add my task setup and closedown into the State directly. Then whenever I needed to create a task for a user, I dragged my &lt;span style="font-style: italic;"&gt;StateWithTask &lt;/span&gt;onto the designer. I had to create some properties (DSN, AssignTo, TaskDescription, TaskOutcome) that could be bound to workflow values.&lt;br /&gt;&lt;br /&gt;The next challenge is for the client app to be able to 'see' what events can be fired and build the list of possible actions from the design rather than hard-code into the application so it automatically&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22724714-115399690978183433?l=devmonster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devmonster.blogspot.com/feeds/115399690978183433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22724714&amp;postID=115399690978183433' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22724714/posts/default/115399690978183433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22724714/posts/default/115399690978183433'/><link rel='alternate' type='text/html' href='http://devmonster.blogspot.com/2006/07/winwf-assigning-tasks-from-state.html' title='WinWF - assigning tasks from a state machine'/><author><name>Quango</name><uri>http://www.blogger.com/profile/14513217379777941843</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22724714.post-114269936286169003</id><published>2006-03-18T08:21:00.000-08:00</published><updated>2006-03-18T08:29:22.876-08:00</updated><title type='text'>Windows Workflow</title><content type='html'>&lt;a href="http://www.windowsworkflow.net"&gt;Windows Workflow&lt;/a&gt; is probably one of the most important technologies to come out of Microsoft since, perhaps Office. It might not seem that way to many people, but as a person who is both a company director and a system developer, I think it's really exciting. At last we have a way of visually representing, managing and controlling the business processes.&lt;br /&gt;&lt;br /&gt;At present I am just learning the WWF system, and it's difficult to determine early how to use the system. For example, should I place as much business logic as possible into the code inside each workflow? Or should the workflow be as much of a 'shell' as possible, with interfaces out to external services and minimal code?&lt;br /&gt;&lt;br /&gt;At present I suspect the latter will be the correct approach, and make WWF as light as possible and just define the process, with the hard work done in components outside WWF.&lt;br /&gt;&lt;br /&gt;As I'm writing an application which may have several different customers, who might want to do similar things (such as credit control) in different ways. So it makes sense that we might have two or three different versions of a workflow process, and we make these modular or pluggable, e.g. through an interface? I will update once I discover this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22724714-114269936286169003?l=devmonster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devmonster.blogspot.com/feeds/114269936286169003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22724714&amp;postID=114269936286169003' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22724714/posts/default/114269936286169003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22724714/posts/default/114269936286169003'/><link rel='alternate' type='text/html' href='http://devmonster.blogspot.com/2006/03/windows-workflow.html' title='Windows Workflow'/><author><name>Quango</name><uri>http://www.blogger.com/profile/14513217379777941843</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22724714.post-114045272531859944</id><published>2006-02-20T08:21:00.000-08:00</published><updated>2006-02-20T08:44:21.583-08:00</updated><title type='text'>Getting the XmlEnum value of an Enum for XML serialization</title><content type='html'>Getting the XmlEnum value of a property is something Serialization does easily, but doing it yourself is quite a challenge.&lt;br /&gt;&lt;br /&gt;I was happy when I finally Googled &lt;a href="http://blogs.msdn.com/haibo_luo/archive/2005/08/28/457318.aspx"&gt;this post&lt;/a&gt; as it enabled me to write this function to determine the Xml value to return.&lt;br /&gt;&lt;br /&gt;The key is to know that an Enum's values are treated as Fields within the Enum. You can then enumerate the fields using GetFields() and search for the field with the value matching your object.&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:78%;"  &gt;&lt;span style="font-size:85%;"&gt;&lt;blockquote&gt;Public Function GetXmlEnumValue(ByVal o As Object) As String&lt;br /&gt;   'Enumerate the values of the EnumType of this object&lt;br /&gt;   For Each enumValue As FieldInfo In o.GetType.GetFields(BindingFlags.Public Or BindingFlags.Static)&lt;br /&gt;       'If this value matches our object, we have the correct&lt;br /&gt;       If enumValue.GetValue(Nothing) = o Then&lt;br /&gt;           'Search for XmlEnumAttributes (there should only be one)&lt;br /&gt;           Dim xmlatt As Xml.Serialization.XmlEnumAttribute = _&lt;br /&gt;                       CType(Attribute.GetCustomAttribute(enumValue, _ &lt;br /&gt;                       GetType(Xml.Serialization.XmlEnumAttribute)), _&lt;br /&gt;                        Xml.Serialization.XmlEnumAttribute)&lt;br /&gt;           Return xmlatt.Name&lt;br /&gt;       End If&lt;br /&gt;   Next&lt;br /&gt;   'Not found&lt;br /&gt;   Return Nothing&lt;br /&gt;End Function&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22724714-114045272531859944?l=devmonster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devmonster.blogspot.com/feeds/114045272531859944/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22724714&amp;postID=114045272531859944' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22724714/posts/default/114045272531859944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22724714/posts/default/114045272531859944'/><link rel='alternate' type='text/html' href='http://devmonster.blogspot.com/2006/02/getting-xmlenum-value-of-enum-for-xml.html' title='Getting the XmlEnum value of an Enum for XML serialization'/><author><name>Quango</name><uri>http://www.blogger.com/profile/14513217379777941843</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22724714.post-114044640497526211</id><published>2006-02-20T06:38:00.000-08:00</published><updated>2006-02-20T06:42:44.546-08:00</updated><title type='text'>Intro</title><content type='html'>Have finally joined the blogging trend as late as I possibly could.&lt;br /&gt;&lt;br /&gt;My blog will mostly be technical stuff relating to development in Visual Studio 2005, in ASP.NET, MS Sql Server 2005, VB.NET and sometimes even C#&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22724714-114044640497526211?l=devmonster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devmonster.blogspot.com/feeds/114044640497526211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22724714&amp;postID=114044640497526211' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22724714/posts/default/114044640497526211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22724714/posts/default/114044640497526211'/><link rel='alternate' type='text/html' href='http://devmonster.blogspot.com/2006/02/intro.html' title='Intro'/><author><name>Quango</name><uri>http://www.blogger.com/profile/14513217379777941843</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
