Threading in ASP.NET : quick start

28 03 2008

Threading. God loves it, and so should you.

It’s pretty easy to get started threading in .NET. So why wait?

But why would you want to multithread? There are plenty of different occasions, but essentially when you have some processes that should run asynchronously. This could include an automatic conversion process for some uploaded file – there’s nothing better than throwing it to a thread (or even a Windows Service) to process. That way, the user doesn’t have to wait for conversion to complete before they get back to your site.

Getting going is pretty easy, the complications come when you start looking at threads that use the same data.

Essentially, you start the Thread either as an empty method call, or by passing it some object. You should at least know what a delegates is first (essentially it is a function that can be passed around like a variable).

Now, I prefer the Parameterised (i’m Aussie, so I don’t like using Z where it’s an S 😛 ) option below just because I often want to pass at least something.

C#

using System.Threading;

ParameterizedThreadStart starter = delegate(object prop){SomeObject.SomeMethod(prop)); };
new
Thread(starter).Start(someObject);

One thing you need to remember here though is, if you are calling this in ASP.NET, then it’s the aspnet_wp.exe process that starts the thread, and if this is killed or restarted somehow, then it will kill your thread also.

It could be killed or restarted for the following reasons:

  • change in global.asax file,
  • change in machine.config,
  • change in web.config
  • change of content of /bin folder
  • IIS service is interrupted (incl restart)
  • Server is restarted

One thing you will learn to love: the Thread.Sleep() method and the System.Threading.Timer class…

Enjoy!

Useful Reference: This article gives a great intro into threads.





Visual Studio 2008 Standard vs Professional and the lack of Windows Services Support

27 03 2008

Ok, well I’ve blogged about the virtues of VS2008 Standard before.

Essentially, I find the Standard version very satisfactory for everyday coding. Even the Server Explorer is there, regardless of what Microsoft’s product comparison says.

One thing that frustrates me however, was that nowhere on the site, did they mention that the creation of Windows Services was a Professional-only inclusion. Huh.

This is the MSDN article explaining the lack of the feature. But checkout the link they have on VS version comparisons and show me where it mentions no Windows Services. Boo.

If you think about it, Services are useful little tools, especially when you have your own server to work with, and you need something running all the time, managing data requests – like a process queuing service for example.

The feature that is missing from Visual Studio is the startup Project Template. However, if you know the startup code, you don’t need the Template.

You can still create an Empty Project in VS2008 Standard, include the System reference and the System.ServiceProcess reference and then add the classes from there. This CodePoint article provides a good insight. Microsoft have their own article – though it’s in VB.NET (ewww).

Personally, I find the best approach is to create a Service.cs file and load the code from the Code Project site. Then you can simply follow Microsoft’s instructions to add an installer.

You then install via your framework’s InstallUtil.exe (again see the Microsoft link). This executable is distributed with the .NET 2.0 Framework, and as such you can find it somewhere like: C:\WINDOWS\Microsoft.NET\Framework\v2.0.

Update: Feb 4, 2008

Another thing I’ve noticed missing is the ability to create Office Add-Ins. These are those tools that you install into the various products of Office. I’m suspicious though that this lack is something that a work around, like the above one, could fix. 

If you’re just looking for interoperability with Office, that’s simply the matter of installing the version of Office you need on your dev machine, and then including the COM reference in your project. (eg. Word is Microsoft Word XX.X Object Library (v 12.0 is 2007, 11.0 is 2003))





Flex.NET remoting methodology – coding standards and best practises

27 03 2008

I’ve been dabbling with different methodologies into Flex.NET remoting, and trying to find a coding standard that works and is appropriate for this technology.

I’ve provided my solution in the hope that it will spur comments and generate other opinions in this rather new field.

One of the annoying things with Flex remoting is having to define the same object twice – once in C# and once in ActionScript 3 (AS3). Obviously as good coders, we know this to be a no-no.

Of course, there are codegen solutions out there, but I’ve been dissatisfied with them, and prefer the manual touch.

This is what I’ve come up with:

  1. In Visual Studio, create a DataSet that interfaces with the database, exposing specific TableAdapters to each of your objects.
  2. In both Flex and .NET, create an object that spans across the two platforms. As it’s defined twice, use some codegen tool to generate the class in both C# and AS3.
  3. In your .NET library, create a “Service” for the action that provides the ability to interface between the client (Flex) and the server (.NET). This service talks to the DB via the above mentioned TableAdapters.
  4. In your Flex application, create a “Service” that mimics the methods of the service in .NET that you want to access

Don’t worry, I never read those summaries either. Here’s the example that explains it all:

Problem: I want to modify a User object across the platform

Solution:

  1. Create my DAL by adding a DataSet to my Service Layer (the assembly that will handle all the .NET interfacing). In the DAL, create a UserTableAdapter and expose a Get method called : GetUserByID(int userID).
  2. Create the object in C# and is AS3 . Note the use of the compiler directive “RemoteClass” in the AS3 is the syntax for WebORB’s remoting solution.
    C# (User.cs)

    namespace JustinJMoses.Examples.RemotingExample.Objects
    {
    public class User
    {
    public int UserID = -1;

           public String GivenNames;

           public String Surname;

           public String Email;
    }
    }

    AS3 (User.as)

    package com.justinjmoses.examples.remotingexample

    {

    [RemoteClass(alias=”JustinJMoses.Examples.RemotingExample.Objects.User”)]

    public class User

    {

    public var UserID:int = -1;

    public var Email:String;

    public var GivenNames:String;

    public var Surname:String;

    }

    }

  3. Make a service for the User in C# – UserService.cs

    using JustinJMoses.Examples.RemotingExample.Objects;

    using JustinJMoses.Examples.RemotingExample.DAL;

    using JustinJMoses.Examples.RemotingExample.DAL.MyDALTableAdapters;

    namespace JustinJMoses.Examples.RemotingExample.Services
    {

    public class UserService
    {

    public User Load(int UserID)
    {

    UserTableAdapter adapter = new UserTableAdapter();

    MyDAL.UserDataTable table = adapter.GetUserByID(UserID);

    MyDAL.UserRow row = (MyDAL.UserRow)table.Rows[0];

    User u = new User();

    u.UserID = row.UserID;

    u.GivenNames = row.GivenNames;

    u.Surname = row.Surname;

    u.Email = row.Email;

    return u;

    }

    }

    }

  4. Make a service for the Flex app in AS3: UserService.as

    package com.justinjmoses.examples.remotingexample
    {

    import mx.rpc.events.ResultEvent;

    public class UserService extends BaseService
    {

    public static function Load(onResultFunction:Function,userID:int):void
    {

    init(“UserService”);

    remoteObject.Load.addEventListener(ResultEvent.RESULT,onResultFunction);

    remoteObject.Load(userID);

    }

    }

    }

    that extends from the base service class BaseService.as

    package com.justinjmoses.examples.remotingexample
    {

    import mx.controls.Alert;

    import mx.core.Application;

    import mx.rpc.events.FaultEvent;

    import mx.rpc.events.InvokeEvent;

    import mx.rpc.events.ResultEvent;

    import mx.rpc.remoting.mxml.RemoteObject;

    public class BaseService

    {

    protected static var remoteObject:RemoteObject = null;

    protected static function init(serviceName:String):void

    {

    remoteObject = null;

    remoteObject = new RemoteObject(“GenericDestination”);

    remoteObject.showBusyCursor = true;

    remoteObject.addEventListener(FaultEvent.FAULT, BaseService.onFault);

    remoteObject.source = “JustinJMoses.Examples.RemotingExample.Services.” + serviceName;

    }

    protected static function onFault (event:FaultEvent):void

    {

    Alert.show(event.fault.faultString, “Error”);

    }

    }

    }

  5. The function can now be called statically in AS3

    private function onCrtComplete():void
    {

    UserService.Load(onUserLoaded, 12);

    }

    private function onUserLoaded(evt:ResultEvent):void
    {

    var user:User = User(evt.result);
    }

NOTE: This soln is done via WebORB remoting. Syntax includes the remote object destination of “Generic Destination”, and the compiler directive “RemoteObject()” in AS3.





New User Interfaces (UI): The developers are listening

14 03 2008

I’m sure you’ve all noticed how devices are continually improving their user interfaces (UI). I only need to refer to two of the current pioneers: Apple and Nintendo.

Notice how many owners feel a kind of attachment to their devices [insert Wii / iPhone / iTouch here] ?

It’s not weird really.

They’ve also spurned a bunch of imitations from competitors who quickly realise the power of enhanced UI. Look at the PS3’s tilt-sensing in their new controllers, Nokia and other’s new touch-interfaces on all of their phones.

I believe the success of these new devices is primarily three-fold (apart from the obvious fact that they’ve been launched by established, well-financed electronics developers).

Firstly, these things feel so much closer to the real-world. I move my Wiimote, Mario rolls along on his ball. (Don’t you dare ask how often I balance on top of a ball in the real-world). I flick through the iTouch artist list, and I feel as though I’m flipping through a real catalogue.

Secondly, the UI is so much easier to get started with. Throw the instruction manual out the window. (Well, don’t literally throw it). The UI is intuitive. I need to zoom in on the iPhone, pinch away. Geez, that was hard. Remember when the iPod came out? OK, so it was a market leader, but the easy interface made it pretty sweet over the competition. Look at the web. v2.0 also shows this simplification of interface design. Sites are now so much clearer and user choices are that much more simple. Thank bloody god.

Thirdly, and consequently, these devices feel more personal. Maybe my Wii feels more personal because i had to wait (it was well worth it). I think there’s more to it though. Because it reacts to my movements, I feel more like a participant and less like a puppeteer.  Even my friends who normally wouldn’t touch a computer game without a look of distaste firmly planted are getting into it.

Ever notice how well weighted the iPod / iTouch /iPhone are? They all feel solid. This isn’t by chance. Apple know that we interact with all of our senses, and that the sense of touch is part of the user experience. Solid and smooth intuitively tells me that the device i hold is a cut-above.

UIs are continually improving, and our $$ are teaching those developers what we want.

Let the good times roll.





Generic Flex DataGrid itemRenderers

12 03 2008

Well, yet again there is the generic item challenge.

One interesting thing is how we handle ItemRenderers (and ItemEditors). Personally, I want little icons as an itemRenderer, such as a Tick or a Cross icon.

To overview, a custom itemRenderer is simply some component that can override the set data property. Other than that it is pretty much any UIComponent in FLex you can think of.

However, Flex passes you the data for that row. So, you need to know the name of the field to access the data for that column. Huh.

Well, yes there is this wonderful little thing called listData but it all depends on the Component you extend in your itemRenderer. I like the trusty old HBox, but lo-and-behold, it doesn’t implement the mx.controls.listClasses.IDropInListItemRenderer interface. Huh. Well, I dont want to use an Image control as my component because it gets scaled to fit the row size (*yuk). But hang on, can I just implement a basic getter/setter for listData and expect the DataGrid to manage it all? ahhh, yes.

MyItemRenderer.mxml

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:HBox
implements=”mx.controls.listClasses.IDropInListItemRenderer” horizontalAlign=”center” xmlns:mx=”http://www.adobe.com/2006/mxml >
<mx:Script>
<![CDATA[

import mx.controls.dataGridClasses.DataGridListData;
import mx.controls.listClasses.BaseListData;
import mx.controls.Image;

private var _data:Object;

// Internal variable for the property value.
private var _listData:BaseListData;

// Make the listData property bindable.
[
Bindable(“dataChange”)]

// Define the getter method.
public function get listData():BaseListData
{

return _listData;
}

// Define the setter method,
public function set listData(value:BaseListData):void
{

_listData = value;

}

override public function set data(value:Object):void {

_data = value;

var icon:Image = new Image();

if (Boolean(_data[DataGridListData(listData).dataField]) === true)
{

//Icons: this is one of my classes, just returns an embedded image
icon.source = Icons.TICK;

this.toolTip = “Yes”;
}

else
{

icon.source = Icons.CROSS;

this.toolTip = “No”;
}

this.removeAllChildren();

this.addChild(icon);

}

override public function get data( ):Object {
return _data;
}

]]>

</mx:Script>
</mx:HBox>

And it is implemented for some DataGrid column thusly:

 

<mx:DataGrid>
<mx:columns>
<mx:DataGridColumn itemRenderer=”MyItemRenderer dataField=”someField />
</mx:columns>
</mx:DataGrid>

 





Generic Flex Datagrid case insensitive sort

11 03 2008

Well, i’m not a big fan of this, but Flex’s Datagrid control doesn’t have a nice little property allowing case-insensitive string sorts.

Huh.

The best solution I could find was on the flexexamples blog. But seriously, who wants to hard code a function every time they want case-insensitive sorting ?

Not I.

How about this soln?

public function doCaselessSortForField(field:String):Function
{

return function(obj1:Object, obj2:Object):int
{

return
mx.utils.ObjectUtil.stringCompare(obj1[field],obj2[field],true);
}

}

Called by a datagrid thusly:

<mx:DataGrid>
<mx:columns>

<mx:DataGridColumn
sortCompareFunction=”doCaselessSortForField(‘Title’)” headerText=”Title” dataField=”Title” />
</mx:columns>

</mx:DataGrid>





WebORB vs FluorineFx

10 03 2008

Updated: September 30, 2008

So, it starts to get interesting here.

I’m noticing some of the sames and some of the stark differences between WebORB, the commercial yet free .NET Flash Remoting tool and FluorineFx, the open source alternative.

To summarise thus far:

Both:

  • Have a Console feature which allows you to see all the classes you are exposing to the remoting client and invoke them.
  • Work with VS2008 (I have only tested the .NET 2.0 framework) and Flex 3.
  • Have a Windows Service feature that allow you to deploy it alongside your AIR application for better client-side functionality (though by nature that must limit them to Windows deployments, no?)

WebORB: (v3.5 for .NET)

  • Is a free product, but commercially owned and closed source.
  • The licensing allows the software to be used in every scenario except redistribution.
  • Has a very comprehensive Console app that handles security on all namespace/class/method levels very nicely.
  • Has very useful codegen tools within the Console to get you going – both for AS and C#/VB.NET.
  • Has reasonable documentation to go along with it (it is still quite lacking in content and organisation)
  • Has a database tool in the Console (WDML) that essentially takes your DB structure and creates a C# or VB.NET Solution interfacing to all tables/views/stored procs. Also creates AS classes to interface with this data.
  • Exposes all of the DLL to the user. However, there is the option in .config file to turn on “closed” method which means you need to turn each service/method you want.
  • Uses a yahoo mail group to communicate between the developers and the users. The support is helpful to a point… they don’t answer every single question on there, but do answer the crux of them generally.

FluorineFx: (v.1.0.0.13 for .NET)

  • Has a Console app also, but with much less functionality than WebORB
  • Has significant multi-framework (Cairngorm, PureMVC, etc) style actionscript codegen.
  • Has documentation but is seriously lacking in examples. Not easy for new users to understand where to go once it’s working.
  • Has a specific implementation of DataSets and DataTables that is not as intuitive as WebORB. A DataTable for example has the “serverInfo” property which when expanded reveals a cursor, the list of columns and the list of data.
  • Has a nice project setup wizard in Visual Studio.
  • Security support for services must all be done manually in the configuration files.
  • Uses C# Attributes to expose classes as Services. (use [RemotingService(“Fluorine sample service”)] above the class definition.
  • Uses a mailing list for communication, and generally everyone is very helpful.
  • Can and will provide quick additions to the code and SVN releases of new versions based on requests/issues in the mailing list.
  • It’s Open Source, so you can actually learn the ins and outs of AMF and remoting. And, if you’re not happy, get in there and modify the code.

I appreciate both products but feel there needs to be a serious overview of documentation, as I’ve read through both and still find myself not 100% sure about the whole system.

Personally, I think Adobe have something to answer for here. I know they are pushing Blaze and I understand that Java-based Blaze is cross-platform and complies to Adobe’s needs… But seriously, C# and Visual Studio are an amazing partnership in developing software, and I won’t give up developing server-side code in them until something as good as it comes out (fingers crossed that Mono keeps plugging away).

I would like to see Adobe step up into this market and help everyone out, because, let’s face it, Flex and AIR don’t meet their potential until they are hooked up into a server-side component.