This blog has moved, permanently, to http://software.safish.com.

Thursday, January 27, 2011

WCF Quick and Dirty

I added some WCF services to an existing project today, and I found I had completely forgotten the easy way of setting this stuff up.  So, here goes.  Note that you will usually split your host and consumer between separate projects – this is just an outline of the basics when working with Visual Studio 2010 and isn’t really concerned with actual implementation.

Create the DataContract Classes

These are the classes that will be serialized and submitted by WCF.  For example, if you are creating a service to add two numbers, you would have a class like so:

[DataContract] 
public class ExampleDataContract 
{ 
 [DataMember] 
 public int Num1 { get; set; } 

 [DataMember] 
 public int Num2 { get; set; } 
} 

Create the Service

Now that we have the data contract, we can create the actual service. 

  1. Navigate to the location in your solution where the service will sit, and add a new item (a WCF Data Service).
  2. The service is now created.  The interface should be decorated with a ServiceContract attribute.
  3. Any methods added to the interface will need to be decorated with an OperationContract attribute.
  4. In terms of the contract implementation, you will need to decorate your class with a ServiceBehavior attribute.  For example:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, AddressFilterMode = AddressFilterMode.Any)] 

Configure the Service

You can manually configure your service in your App.config file, but there is actually a GUI that makes this a lot easier.  All you need to do is righ-click your config file and there will be an option to Edit WCF Configuration – click this to launch the editor.

Note that if your project is not a WCF project, this may not be available in the context menu.  There’s an easy work-around for this though:

    1. Select Tools->WCF Configuration Editor from the Visual Studio menu, and click WCF Configuration Editor
    2. Close the WCF Configuration Editor

Now when you right-click the App.config the Edit WCF Configuration option should be available.

Usually there shouldn’t be too much to change here unless you’re manually creating your endpoints/services.  If you’re just wanting the basic endpoints, you can give the endpoints names (e.g. AddNumbersHttp for the wsHttpBinding) and continue.

We now have enough set up to host and test the service.

Test the Service

Visual Studio 2010 makes testing WCF apps really simple.  If you’re working with a WCF project, when you run the project Visual Studio will fire up the WCF test client by itself.

If you’re developing a web project, this won’t work, so you will need to fire up the client manually by opening a Visual Studio Command Prompt and typing the following:

wcftestclient http://yoursite/Services/YourService.svc.

If you get errors here, you may need to configure your web site.  There are two possible issues:

  1. IIS has not been configured to handle the .svc extension.  This is easily fixed by running the registration tool that comes with .NET – run ServiceModelReg.exe -i from the "%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation" directory
  2. If you are getting an error that the service cannot be activated because it does not support ASP.NET compatibility you can either configure your application for compatibility mode, or mark your service implementation with the following attribute:
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

Create the Client

You can now create the client that will consume the services created above. 

  1. Right-click your project’s References, and click Add Service Reference
  2. If you want to use a service within another project in your solution, you can click the Discover button and select Services in Solution
  3. Select the service, and enter a namespace that will be used within the client project to refer to the service
  4. You can now use the service like any other C# class, for example:
    MyServiceNamespace.MyServiceClient client = new MyServiceNamespace.MyServiceClient();
    client.AddNumbers(1, 2);
    client.Close();
    

Resources

  1. http://msdn.microsoft.com/en-us/netframework/dd939784
  2. http://channel9.msdn.com/shows/Endpoint/Endpoint-Screencasts-Creating-Your-First-WCF-Service/

Wednesday, November 17, 2010

Determining the target .NET Framework version of a .NET assembly

To determine which version of the .NET framework an assembly supports, you can use ILDASM.

Open up a visual studio command prompt, and type the following:

ildasm.exe C:\Yourdll.dll /metadata[=MDHEADER] /text /noil

You’ll get a large amount of indecipherable data, but right at the top, you’ll see something to the effect of

// Metadata section: 0x424a5342, version: 1.1, extra: 0, version len: 12, version: v4.0.30319

where the highlighted piece gives you the supported version.

Alternatively, you can just open ildasm (just type ildasm at the command prompt), and open up the dll – you can see the metadata version right at the top by double-clicking “MANIFEST”:

Mainfest

Useful!

Tuesday, November 16, 2010

Moq BadImageFormatException with NUnit

I ran into an issue today running a unit test where I kept getting a System.BadImageFormatException on the test dll. I incorrectly assumed this was NUnit - after digging around a bit I worked out it was actuall Moq that was the source of the problem.

The return value of the object being verified existed in an assembly that was not being referenced by my test project, and Moq was falling over. Adding the reference sorted out the problem.

The exact error I encountered was:

Test.MyLongNamespace.MyTestmethod: System.BadImageFormatException : [C:\Users\matt salmon\AppData\Local\Temp\nunit20\ShadowCopyCache\9748_634255057586445703\Tests_64256578\assembly\dl3\5181e02b\57ddb865_7585cb01\MyAssembly.DLL] The signature is incorrect.

Friday, November 12, 2010

Rebuilding SQL Server Indexes

I've always used cursors to rebuild indexes in SQL Server, like so:

USE YourDatabase

DECLARE @tableName varchar(255)
DECLARE cur CURSOR FOR

SELECT table_schema + '.' + table_name 
FROM information_schema.tables
WHERE table_type = 'base table'

OPEN cur

FETCH NEXT FROM cur INTO @tableName
WHILE @@FETCH_STATUS = 0
BEGIN
	DBCC DBREINDEX(@tableName,' ',90)
	FETCH NEXT FROM cur INTO @tableName
END

CLOSE cur
DEALLOCATE cur

However, I discovered a much easier way to do it today:

sp_MSforeachtable @command1="print '?' DBCC DBREINDEX ('?')"

This is an undocumented stored procedure that I didn't even know existed until this morning. The cursor route is still useful for when you want to exclude tables, but dang....I wish I'd known of this earlier.

Wednesday, October 13, 2010

Playing with the TPL

I did a quick investigation on the Task Parallel Library (TPL) this morning (part of the System.Threading library which comes included in the .NET 4.0 framework or is available as a download from 3.5), and I’m really amazed at how easy it was to implement, and the apparent benefits of using it.  Basically, this library allows you to benefit from the multiple cores found in modern computers, without the pain of actually coding for multiple cores yourself. 

I wrote a very simple C# application that fired off 1,000 web requests to a web application on my local machine and read the response stream.  This was done in three ways:

  1. sequentially making the web request in a for loop
  2. using a thread pool to make the web requests
  3. using Parallel.Invoke to make the web requests with the TPL library

Well, option 1 was obviously very simple to implement, but it was SLOW.  1,000 requests took in the region of 20 seconds to run.

Option 2 was the most difficult to implement, but obviously far more efficient.  I always find coding for multiple threads a little tricky, as I don’t do it often and I never remember offhand where to put the wait handlers.  Anyway, it resulted in 1,000 requests being done in approximately 11 seconds.

Option 3 was, to my pleasant surprise, a piece of cake to implement.  Create an Action list, and call Parallel.Invoke – that was it.  Incredibly, this took approximately 6.5 seconds to run on my 4-core machine.  I’ve pasted the code below, and hopefully my implementation is correct, but it’s so easy to use I don’t see why you wouldn’t use it when you have a large number of tasks to do at one time.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Net;
using System.IO;
using System.Threading;

namespace TplSample
{
    class Program
    {
        static string url = "http://dev.mysite.co.za/";
        static int testCount = 1000;

        static void Main(string[] args)
        {


            // fire off one request so we aren't skewed by a sleeping application pool
            SendWebRequest();

            // fires off requests in sequential fashion
            SingleRequests();
            // fires off requests using a thread pool
            MultiThreaded();
            // fires off requests using parallel processing
            ParallelRequests();

            Console.WriteLine("Done.");
            Console.ReadLine();
        }

        static void SingleRequests()
        {
            // fire off the web request 1,000 times, and time it
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < testCount; i++)
            {
                SendWebRequest();
            }
            sw.Stop();
            Console.WriteLine("Single requests: {0} seconds", sw.Elapsed.TotalSeconds);

        }

        static void ParallelRequests()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            List actions = new List();
            for (int i = 0; i < testCount; i++)
            {
                Action a = new Action(SendWebRequest);
                actions.Add(a);
            }
            Parallel.Invoke(actions.ToArray());
            sw.Stop();
            Console.WriteLine("Parallel requests: {0} seconds", sw.Elapsed.TotalSeconds);
        }

        static void MultiThreaded()
        {
            // ThreadPool.SetMaxThreads(10, 10);
            Stopwatch sw = new Stopwatch();
            sw.Start();

            List doneEvents = new List();
            for (int i = 0; i < testCount; i++)
            {
                ManualResetEvent resetEvent = new ManualResetEvent(false);
                doneEvents.Add(resetEvent);
                ThreadWrapper tw = new ThreadWrapper(resetEvent);
                WaitCallback callBack = new WaitCallback(tw.ThreadPoolCallback);
                ThreadPool.QueueUserWorkItem(callBack);

                if (doneEvents.Count == 64)
                {
                    WaitHandle.WaitAll(doneEvents.ToArray());
                    doneEvents.Clear();
                }
            }

            if (doneEvents.Count > 0)
            {
                WaitHandle.WaitAll(doneEvents.ToArray());
            }
            sw.Stop();
            Console.WriteLine("Thread pool requests: {0} seconds", sw.Elapsed.TotalSeconds);
        }

        static void SendWebRequest()
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            req.Method = "GET";

            HttpWebResponse webResponse = (HttpWebResponse)req.GetResponse();
            using (StreamReader responseStream = new StreamReader(webResponse.GetResponseStream()))
            {
                string response = responseStream.ReadToEnd();
                responseStream.Close();
            }
            webResponse.Close();
            //Console.WriteLine("1");
        }

        public class ThreadWrapper
        {

            private ManualResetEvent doneEvent;


            public ThreadWrapper(ManualResetEvent doneEvent)
            {
                this.doneEvent = doneEvent;
            }

            public void ThreadPoolCallback(Object threadContext)
            {
                SendWebRequest();
                this.doneEvent.Set();
            }


        }
    }
}

Tuesday, September 21, 2010

Prettify

Following stackoverflow’s example, I’ve started using prettify for syntax highlighting on this blog.  I’ve used the Google syntax highlighter in the past, but prettify just seems easier as I don’t need to mark it with class names or anything – all I need to do is wrap code in <pre> and <code> tags, and it just works.  It’s clever enough to work out the language.

Getting it working was really simple.  I downloaded the source, combined all the .js files into one using Google’s Closure Compiler, and update the .css file to the styles I like (stolen without shame from stackoverflow – I love that site).

To get the styles to apply to my blog, I also added an initialisation script to make the prettify call, and it works.  Hopefully this should save me some time in the future.

I found a really good article here that showed me how to set this all up.  I’ll update old blog posts at some stage, for now they’re going to appear without styling.

Wednesday, September 8, 2010

.NET – Detecting Modem COM Ports

We have a project at the moment where we’re using GSM modems attached to the local machine to send an SMS.  One of the issues we’ve had is when the modem is not actually connected before our service starts up: our service sometimes attaches to the COM Port that is required by the modem, and this prevents the modem from ever connecting.

There is a simple way to detect which COM ports are assigned to modems installed on your machine:

using System.Management;

ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_POTSModem");
foreach (ManagementObject mo in mos.Get())
{
    string s= mo["AttachedTo"].ToString();
}

Other properties available can be looked up here: http://msdn.microsoft.com/en-us/library/aa394360%28VS.85%29.aspx