Personal

  • Hosting Windows Workflow Foundation in a Console Application without Ugly Code

    I’ve been using Windows Workflow Foundation for a small personal project to learn more about it and see what it can do. It’s pretty powerful and I’m looking forward to delving more into it. For my purposes though, I’m hosting the workflow in a console program.

    If you look around the internet, you’ll see lots of examples of hosting a sequential workflow in a synchronous manner, even though the WorkflowRuntime only support asynchronous operations. That code usually looks like this (example adapted from wf-training-guide.com to add support for input/output arguments):

    static void Main(string[] args)
    {
      Dictionary<string, object> inputArguments = new Dictionary<string, object>();
      inputArguments.Add("Argument1", args[0]);
      Dictionary<string, object> outputArguments;
        
      // Create the WF runtime.
      using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
      {
        // Hook into WorkflowCompleted / WorkflowTerminated events.
        AutoResetEvent waitHandle = new AutoResetEvent(false);
        workflowRuntime.WorkflowCompleted
          += delegate(object sender, WorkflowCompletedEventArgs e)
            {
              outputArguments = e.OutputParameters;
              waitHandle.Set();
            };
    
        workflowRuntime.WorkflowTerminated
          += delegate(object sender, WorkflowTerminatedEventArgs e)
            {
              Console.WriteLine(e.Exception.Message);
              waitHandle.Set();
            };
    
        // Create an instance of the WF to execute and call Start().
        WorkflowInstance instance =
          workflowRuntime.CreateWorkflow(typeof(WorkflowClass));
        instance.Start();
    
        waitHandle.WaitOne();
      }
    }

    Unfortunately, that’s a ton of code to do only a few things:

    1. Take input arguments
    2. Instantiate a WorkflowRuntime
    3. Create a workflow instance
    4. Run the workflow
    5. Handle any exceptions (poorly)
    6. Return output parameters from the workflow
    7. Do all of this in a synchronous manner.

    What if we could just call a method similar to this:

    var outputArguments = RunWorkflow<WorkflowClass>(arguments, completedEvent, terminatedEvent);

    Well, now you can! I’ve written this wrapper class to allow exactly that:

    public class WorkflowManager
    {
      public static Dictionary<string, object> RunWorkflow<T>(
        Dictionary<string, object> arguments,
        EventHandler<WorkflowCompletedEventArgs> completedEvent,
        EventHandler<WorkflowTerminatedEventArgs> terminatedEvent)
        where T : SequentialWorkflowActivity
      {
        using (WorkflowRuntime runtime = new WorkflowRuntime())
        {
          Dictionary<string, object> returnValue = null;
          Exception ex = null;
    
          using (AutoResetEvent waitHandle = new AutoResetEvent(false))
          {
            WorkflowInstance instance = runtime.CreateWorkflow(typeof(T), arguments);
            runtime.WorkflowCompleted += (o, e) =>
            {
              EventHandler<WorkflowCompletedEventArgs> temp = completedEvent;
              if (temp != null)
              {
                temp(o, e);
              }
    
              returnValue = e.OutputParameters;
    
              waitHandle.Set();
            };
    
            runtime.WorkflowTerminated += (o, e) =>
            {
              EventHandler<WorkflowTerminatedEventArgs> temp = terminatedEvent;
              if (temp != null)
              {
                temp(o, e);
              }
    
              ex = e.Exception;
    
              waitHandle.Set();
            };
    
            instance.Start();
            waitHandle.WaitOne();
          }
    
          if (runtime != null)
          {
            runtime.StopRuntime();
          }
    
          if (ex != null)
          {
            throw ex;
          }
    
          return returnValue;
        }
      }
    }

    Now you really can run the above code to execute your workflow in a synchronous manner without all kinds of messy code. Beware creating multiple WorkflowRuntime instances though. If you are managing multiple simultaneous workflows, you’ll need to pass in instance IDs and keep track in the runtime of which one is completing or throwing errors. It’s generally a bad idea to have multiple WorkflowRuntimes.

    Enjoy now being able to write:

    var outputArguments = RunWorkflow<WorkflowClass>(arguments, completedEvent, terminatedEvent);

  • Chase Visa Fraud

    I just got a call from the Chase fraud computer voice. He told me that somebody had just charged my card about $250 to a clothing website called ASOS.com. He asked if it was me and I kept pressing zero so I could talk to a person. I knew if I said it wasn’t me that they would just close my card and send me a new one in about a week more or less.

    I finally got a person (in India of course), and she told me that not only had they charged that to my card, but also $1.00 to Apple’s iTunes store on February 25th. I didn’t even see that show up in my online activity today on Chase’s web site, so I assume they deactivated the charge when they figured out it was fraud. I assume the Apple charge was to test the card for validity.

    I told the lady that a week was unacceptable, because I put everything on that Chase Freedom card. I told her I needed it tomorrow. She obliged without any complaint; she said it will be here tomorrow via UPS and I will have to sign for it. I told her that’s no problem since I work from home.

    Kudos to Chase for their aggressive, accurate anti-fraud algorithms and their customer service relating to shipping out a card overnight upon request.


  • redgate Releases SQL Search for Free

    redgate has released their SQL Search 1.0 for free, and my coworker Stephen sent our team an email letting us know about it. It is a fantastic product that integrates with SSMS and now it’s free. It keeps an index of all the text in every sproc, all the columns in every table, etc, and you can search them all instantly, limiting by type and many other options.

    These are the features they list on their page:

    • Find fragments of SQL text within stored procedures, functions, views and more
    • Quickly navigate to objects wherever they happen to be on your servers
    • Find all references to an object
    • Integrates with SSMS

    And their “Why use SQL Search?”:

    • Impact Analysis
      You want to rename one of your table columns but aren’t sure what stored procedures reference it. Using SQL Search, you can search for the column name and find all the stored procedures where it is used.
    • Work faster
      Finding anything in the SSMS object tree requires a lot of clicking. Using SQL Search, you can press the shortcut combo, start typing the name, and jump right there.
    • Make your life easier
      You need to find stored procedures you’ve not yet finished writing. Using SQL Search, you can search for stored procedures containing the text ‘TODO’.
    • Increase efficiency, reduce errors
      You are a DBA, and developers keep using ‘SELECT *’ in their views and stored procedures. You want to find all these and replace them with a correct list of columns to improve performance and prevent future bugs. Using SQL Search, you can look for ‘SELECT *’ in the text of stored procedures and views.

    If you are a user of SQL Server Management Studio, I highly recommend you check out out. You sure can’t beat the price. Check out the screenshots below as well.