Wednesday, January 26, 2011

WPF - Performance Improvement for MVVM Applications - Part # 1

This is a series of posts about performance improvements of an MVVM based applications. You can find the other posts here:

- Part 2 : http://shujaatsiddiqi.blogspot.com/2011/02/wpf-performance-improvement-for-mvvm.html

- Part 3: http://shujaatsiddiqi.blogspot.com/2011/03/wpf-performance-improvement-for-mvvm.html

In this example we are discussing the various performance improvement for a WPF Binding developed using MVVM. This is for enhancing user experience by increasing the responsiveness of the system. MVVM based application is highly dependent upon the WPF Binding system. I think if we use certain features of Binding system then we can achieve this.
<Window x:Class="WpfApplication_ASync_Binding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication_ASync_Binding"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<TextBlock  Height="56" HorizontalAlignment="Left"
Margin="40,71,0,0" Name="label1" VerticalAlignment="Top"
Width="434" Background="Aquamarine" >
<TextBlock.Text>
<Binding Path="StudentName" StringFormat="testtt:{0}" />
</TextBlock.Text>
</TextBlock>
</Grid>
</Window>

We are not changing the code behind of the view so it should be as created by default. The view model:
namespace WpfApplication_ASync_Binding
{
using System.ComponentModel;

class MainWindowViewModel : INotifyPropertyChanged
{
private Student _student;
public MainWindowViewModel()
{
_student = new Student();
} 

private string _studentName;
public string StudentName
{
get
{
return _student.StudentName;
}
set
{
_student.StudentName = value;
OnPropertyChanged(StudentName);
}
} 

public event PropertyChangedEventHandler PropertyChanged; 

private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}

The view model is using _student as model. This is an instance of Student class. As you can see StudentName is just a proxy property for the model’s property named StudentName. The definition of Student is as follows:
namespace WpfApplication_ASync_Binding
{
class Student
{
public string StudentName { get; set; } 

public Student()
{
StudentName = "Muhammad";
}
}
}

Let’s run this application. The output should appear as follows:


Now let’s change this a bit. Let’s consider Student is using some complex logic for its property StudentName. It might be using a web service which might be slow. Now since we are using proxy property for binding this delay would slow down the binding and the form would become idle. Let’s create this scenarios by just introducing a delay using Thread.Sleep() as follows:
namespace WpfApplication_ASync_Binding
{
class Student
{
private string _studentName;
public string StudentName
{
get
{
//imaginary delay
Thread.Sleep(10000);
return _studentName;
}
set { _studentName = value; }
}

public Student()
{
StudentName = "Muhammad";
}
}
}

Now run the application. The same form would display but after a delay of atleast 10 seconds.

Basically when Binding system would access the getter for StudentName property in the DataContext. It would be delayed because the view model would be trying to get the Model’s property resulting in a delay of atleast 10 seconds (because of Thread.Sleep). So form instance is created. It assigns the DataContext as MainWindowViewModel in InitializeComponent. When it attempts to bind the Text property of TextBlock. It experiences this delay. So the delay is because of binding. If this binding becomes asynchronous then the performance could improve. You should be glad to learn that WPF Binding system supports making its binding asynchronous by providing IsAsync property in Binding markup extension. Let’s use this!

We update the view as follows:
<TextBlock.Text>
<Binding Path="StudentName" StringFormat="testtt:{0}" IsAsync="True" />
</TextBlock.Text>

Now run this. The form appears as follows:


This would be shown like this for atleast 10 seconds. During this time, it starts a ThreadPool thread on the background to get the Binding source. As soon as the source property becomes available, the binding updates the view as follows:


Well this is good but user sees nothing on the screen for atleast 10 seconds. We might want to show something else to the user until the data becomes available as a fallback mechanism. WPF binding system supports that too. You can achieve that by setting FallBackValue propery of Binding as follows:
<TextBlock.Text>
<Binding Path="StudentName" StringFormat="testtt:{0}"
IsAsync="True" FallbackValue="Test Fallback value" />   
</TextBlock.Text

Now run the application. The window is shown as follows:


This is shown like that for 10 seconds showing the Fallback value for Binding. You can see that StringFormat is not applied for FallbackValue. After 10 seconds, it updates itself as follows:


In order to have more sophisticated fallback mechanism, you might want to consider Priority Binding.

http://shujaatsiddiqi.blogspot.com/2010/09/wpf-priority-binding.html

The world is not simple. Let’s make it a little complex by updating the constructor of our model (Student) as follows:
public Student()
{
StudentName = "Muhammad";
Thread.Sleep(20000);
}

This is to simulate the 20 seconds further delay in Binding. Let’s run the application. For 20 seconds, nothing appears on the screen. After that the window appears with the fallback value. The fallback value remains on the view for 10 seconds. After that the view is updated with the finalized value for StudentName with applied StringFormat. Now the main question is why this window appears after 20 seconds when binding is asynchronous. Basically Binding.IsAsync just makes the Binding asynchronous. If there is a delay in the construction of DataContext, this would still be on the UI thread hence synchronous. The construction of DataContext (MainWindowViewModel) is causing this delay because of delay of instantiation of the Student (model) in the constructor of view model [Thread.Sleep(20000)].

In order to improve this behavior we can update the way DataContext is constructed. We can construct the object using ObjectDataProvider. This is to utilize the asynchronous instantiation feature of ObjectDataProvider. We can cause asynchronous construction by setting IsAsynchronous for ObjectDataProvider. Let’s update the definition of the section of XAML for view where we are assigning DataContext as follows:
<Window.DataContext>
<ObjectDataProvider ObjectType="{x:Type local:MainWindowViewModel}" IsAsynchronous="True"  />
</Window.DataContext>

Now run the application. As we run the application there is no delay and the following screen appears:


This is maintained for 30 seconds. The 20 seconds is for the construction of DataContext (causing construction of model) and the other 10 seconds is for the delay in the getter for StudentName property from DataContext. Basically the Fallback value is maintained until the value is available no matter the delay is called by the DataContext construction or the available of its property.

10 + 20 = 30 seconds

Eventually the window is updated as follows:


Download:

Sunday, January 23, 2011

C# Static Members' Not-So-Famous features

In this post we will be discussing some known but not-so-famous features of static members in C#. It is possible that you might be already aware of these special features.

Static Members and Application Domains:
Application domains are provided in a .net process to provide intra-process isolation. This isolation also includes the isolation of static members. Static members are static (shared) within the context of an application domain. It includes static fields, classes and constructors. As we know that:

Static Constructor is executed only once for a type

Now lets update this knowledge:

Static constructor is executed only once for a type PER APPLICATION DOMAIN

Let's consider Student class. This class only has a single static member MessageOfTheDay.

class Student
{
public static string MessageOfTheDay = "Default Message";
}

We create a Window as follows:

<Window x:Class="WpfApplication_Generic_Static.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid>
<Label Content="Message Of The Day" Height="27" HorizontalAlignment="Left" Margin="8,0,0,0"
Name="labelMessage" VerticalAlignment="Top" Width="200" FontWeight="Bold" />
<TextBox Height="231" HorizontalAlignment="Left" Margin="8,23,0,0"
Name="textBoxMessage" VerticalAlignment="Top" Width="481" />
<Button Content="Demonstrate static variables across AppDomains" Height="34" HorizontalAlignment="Left" Margin="6,265,0,0"
Name="btnSetMessage" VerticalAlignment="Top" Width="292" Click="btnSetMessage_Click" />
</Grid>
</Grid>
</Window>

The code behind of the Window is as follows:

public partial class MainWindow : Window
{
AppDomain appDomain;
public MainWindow()
{
InitializeComponent();
appDomain = AppDomain.CreateDomain("MyNewDomain");
}

private void btnSetMessage_Click(object sender, RoutedEventArgs e)
{
Student.MessageOfTheDay = this.textBoxMessage.Text;
appDomain.DoCallBack(displayMessage);
displayMessage();

}

private static void displayMessage()
{
string message = string.Format("AppDomain Name: {0}\n\nMessage of the Day: {1}",
AppDomain.CurrentDomain.FriendlyName, Student.MessageOfTheDay);

MessageBox.Show(message);
}
}

As you can see this Window has a single text box and a button. Clicking the button handles the Click event of the button using btnSetMessage_Click handler. The handler assigns a new value to MessageOfTheDay static member of Student class. This also executes displayMessage callback in a different application domain appDomain and shows the value of Student.MessageOfTheDay in this application domain. In order to prove that the current domain still holds the text entered in the textbox, we are showing the value [in the Base AppDomain] of Student.MessageOfTheDay. Let's run this and enter some text in the TextBox. Let's Enter "Muhammad Siddiqi".



So after clicking the button there would be two message boxes displayed. Can you guess the messages in those message boxes?

Based on the above discussion, the following message boxes are displayed:





This proves our point. Although we have set Student.MessageOfTheDay in the current domain but the change is not visible in the other domain as they are isolated.

Static Member initialization and Static constructors:
If we are setting the value of a static field in initializer and static member. What value would it hold? The answer is whatever would be executing last would be resulting in the value of static field. In a previous post, we have discussed about this:



In words: Initializers are executed from child class to base class. The same is true for the value assignment to the constructors in the inheritance hierarchy. The constructors, themselves, are executed from Base class to child class. Additionally, the constructors are always executed when both initializers are value assignment is finished. So in the case of static members also, the static initializer is always executed before static constructor. Based on this discussion, you would always find the value of a static field as set in the static constructors when you would use it first time if they are set in both static initializer and static constructor.

Let's have a class named Banner as follows:

static class Banner
{
public static string MessageOfTheDay = "Default Banner Message";

static Banner()
{
MessageOfTheDay = "Default Banner Message from static constructor";
}
}

Since Banner has only static members, we can declare itself as static. Now if we execute the following code, you can guess what should be displayed:

private void btnBannerMessage_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(Banner.MessageOfTheDay);
}

This results in the following MessageBox:



This is exactly as we discussed above.

Generics and their Static Members:
As we know that for a Generic type, The whole new set of classes are generated for generic classes for each specialized usage by JIT compiler at runtime. That is why static members in a Generic are not shared across different type of TypeMembers. They are only shared within similar TypeMembers. Here TypeMember:
class Classlt;TypeMember>
{
TypeMember StaticField;
}

Let us declare a generic class MyItem as follows:

class MyItem <T>
{
public static T Item { get; set; }
}

Now we use this class as follows:

private void btnGenericItem_Click(object sender, RoutedEventArgs e)
{
//int type for Generic Type
MyItem<int>.Item = 1;

//decimal type for Generic Type
MyItem<decimal>.Item = 2.3m;

//Showing message box for verification
MessageBox.Show(
string.Format("MyItem<int>.Item : {0}, MyItem<decimal>.Item : {1}",
MyItem<int>.Item.ToString(), MyItem<decimal>.Item.ToString()));
}

Can you guess what would be the contents of the MessageBox?

Now verify if it matches from actual Message box.



As you can see that both specific type generated for Generic holds different values of static members, so they are not shared.

Summary:
As a summary of this discussion:

1. Static members are not shared across application domain.
2. Static constructors are always executed after static initializers.
3. Static members are not shared across different specific type generated for Generics.

Download:

WPF - Inter-Domain Messaging using AppDomain Slots

In this post we will discuss Named slot. Slots are used for inter-domain messaging. A sender from one application domain sets the message in other application domain. Any receiver in the other domain can receive the message from the slots.



Let's define a Window to demonstrate the usage of AppDomain's slot to send and receive message to the Application Domain.

<Window x:Class="AppDomain_Slots.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Main Window" Height="350" Width="525">
<Grid>
<Label Content="Message" Height="27" HorizontalAlignment="Left" Margin="8,0,0,0"
Name="labelMessage" VerticalAlignment="Top" Width="96" FontWeight="Bold" />
<Button Content="Send Message" Height="34" HorizontalAlignment="Left" Margin="12,265,0,0"
Name="btnSendMessage" VerticalAlignment="Top" Width="150" Click="btnSendMessage_Click" />
<Button Content="Receive Message" Height="33" HorizontalAlignment="Left" Margin="337,265,0,0"
Name="btnReceiveMessage" VerticalAlignment="Top" Width="154" Click="btnReceiveMessage_Click" />
<TextBox Height="231" HorizontalAlignment="Left" Margin="8,23,0,0"
Name="textBoxMessage" VerticalAlignment="Top" Width="481" />
</Grid>
</Window>

Instantiating Application Domain:
Let's create a new application domain appDomain. We assign it a friendly name MyNewDomain.
AppDomain appDomain;

public MainWindow()
{
InitializeComponent();
appDomain = AppDomain.CreateDomain("MyNewDomain");
}

Sending message to Application Domain:
Let's write some message in a named slot of the application domain. The name of the slot is MyMessage. We will be using the text entered in the Message text box.
private void btnSendMessage_Click(object sender, RoutedEventArgs e)
{
string message = this.textBoxMessage.Text;
appDomain.SetData("MyMessage", message);
}

Receiving message in Application Domain:
Now let's receive this message in the other application domain. We would be getting this message in a callback executed in the other application domain using DoCallBack method. Since displayMessage is a static method, we don't need to serialize it.
private void btnReceiveMessage_Click(object sender, RoutedEventArgs e)
{
appDomain.DoCallBack(displayMessage);
}

static void displayMessage()
{
string message = (string)AppDomain.CurrentDomain.GetData("MyMessage");

MessageBox.Show(string.Format("Domain: {0}, Message: {1}",
AppDomain.CurrentDomain.FriendlyName,
message));
}

Let's enter some text in the Text box and hit Send Message button. This would write message to the slot MyMessage in MyNewDomain application domain.



Now click Receive Message button. This would get data as in the slot and show it in the message box as follows:



Download:

Saturday, January 22, 2011

WPF - Messaging using .net Remoting

Objects in different processes and application domains can not communicate directly. .net Remoting is a technology to provide this for such communication. Before WCF, this has been the only technology available in .net for inter-process and inter-domain messaging. After WCF, it is not recommended for inter-process communication.

From MSDN:
This topic is specific to a legacy technology that is retained for backward compatibility with existing applications and is not recommended for new development. Distributed applications should now be developed using the Windows Communication Foundation (WCF).

Since now we have this idea that it is a legacy technology for inter-process communication, we would not be discussing it for this purpose. We would just be focusing on inter-domain and intra-process messaging using .net Remoting.

Creating Proxies:
Based on the above discussion we have some idea about what .net remoting is all about. We have this idea that in order to pass message to the remote object we need to use a proxy. So the main question is how to create a proxy. It is very easy to create proxy for an instance in another application domain. We just need to use CreateInstanceAndUnWrap method on the other application domain specifying the name of type and the assembly containing the type.

AppDomain has a variety of CreateInstance methods. They are as follows:

1. CreateInstance (4 overloads)
2. CreateInstanceAndUnwrap (4 overloads)
3. CreateInstanceFrom (4 overloads)
4. CreateInstanceFromAndUnwrap

As you can see that each of the above four methods has 4 different overloads supporting the the very details of the required instantiation. It is difficult to decide which of these methods to use to instantiate. But the most important thing is that each of these methods would create an instance in the other application domain and return a proxy of the object so that it could be used by the requester. It must be remembered that we can not create proxies unless they are fit for remote instantiation. Only those types which inherit from MarshalByRefObject. Otherwise if we attempt to instantiate a type, it results in SerializationException.



This resulted while creating an instance of Student type.

public class Student
{
public string studentName { get; set; }

public void showStudentName()
{
MessageBox.Show(studentName);
}
}

If we just change our type a bit by inheriting from MarshalByRefObject, everything becomes fine.

public class Student : MarshalByRefObject
{
public string studentName { get; set; }

public void showStudentName()
{
MessageBox.Show(studentName);
}
}

MSDN says the following about MarshalByRefObject:

MarshalByRefObject is the base class for objects that communicate across application domain boundaries by exchanging messages using a proxy. Objects that do not inherit from MarshalByRefObject are implicitly marshal by value. When a remote application references a marshal by value object, a copy of the object is passed across application domain boundaries.

Garbage Collection for Proxies:
It should be good to learn that the remote object in other domain is destroyed if there is no use for five minutes. This is called the Lease-Based mechanism. This is provided by CLR automatically for remotely created objects. We can override this behavior by overriding InitializeLifetimeService method of MarshalByRefObject.

Though the return type of this method is System.Object This should return an an object implementing ILease.You can read more about this here:

http://msdn.microsoft.com/en-us/library/system.marshalbyrefobject.initializelifetimeservice.aspx

Remoting Vs Copying:
With remoting, the object is present in other application domain. All the operation on the object are actually executed on this remote domain. The other option is cloning. We can achieve this if the object is serializable either by implementing ISerializable or with [Serializable] attribute.

Let us update the definition of Course as follows:

[Serializable]
public class Course //: MarshalByRefObject
{
public int CourseId { get; set; }
public string CourseName { get; set; }

public override string ToString()
{
return string.Format("AppDomainName: {0}\n Id: {1}, Name: {2}",
AppDomain.CurrentDomain.FriendlyName , CourseId.ToString(), CourseName);
}
}

Here we have updated the Course by commenting out the inheritance from MarshalByRefObject and specifying the [Serializable] attribute. Let us also update the definition of setCourseMethod as follows:

public void setCourse(Course course)
{
this.studentCourse = course;
studentCourse.CourseId = 2;
studentCourse.CourseName = "Updated Course";
}

We are just updating the Id and name of the course. Now we use this as follows:

private void button1_Click(object sender, RoutedEventArgs e)
{
AppDomain appDomain = AppDomain.CreateDomain("MyAppDomain");

Student student = (Student)appDomain.CreateInstanceAndUnwrap(
"OtherAsembly",
typeof(Student).FullName);

student.studentName = "Muhammad";

Course course = new Course() { CourseId = 1, CourseName = "Fault Diagnosis & Reliable Systems Design" };

//This would create a copy for student object in MyAppDomain keeping the other object in the current domain
//student.studentCourse = course;
student.setCourse(course);

//student object proxy. This would be using MyAppDomain's copy of Course Object
MessageBox.Show(string.Format("From remote domain:\n{0}", student.ToString()));

//local course object
MessageBox.Show(string.Format("From Calling domain:\n {0}", course.ToString()));
}

As it is apparent from the above code, this would result in two message boxes, one after the other. setCourse serializes the course object and passes it to the other application domain where a new copy of Course is instantiated. Based on this discussion the updates in setCourse() method applied to the Course object should not be available in the original copy. Let's see the message boxes displayed.

First Message Box:


Second Message Box:



Now it is logical to think what happens when a type is both serializable and it also inherits MarshalByRefObject. In this case MarshalByRefObject's effect takes over and a remoting takes place instead of cloning. Let's update Course as follows:
[Serializable]
public class Course : MarshalByRefObject
{...}

Now execute the same code and see the message boxes displayed.

First Message Box:



Second Message Box:



Proxies generating other proxies:
It is also possible for proxies to generate other proxies. They can be generated when a method is called on the proxy and it returns some other instance. They can also be generated when we get some property of the proxy which is also an instance type. All such instances have the same requirements as we have discussed above are still applicable i.e. inheriting MarshalByRefObject for remoting or being serializable for cloning.

Let's define a new class called Degree as follows:

public class Degree
{
public string DegreeName { get; set; }
}

We use this for our Student as follows:

public class Student : MarshalByRefObject
{
public string studentName { get; set; }
public Course studentCourse { get; set; }

public Student()
{
this.studentDegree = new Degree();
}

//public override string ToString()
//{
// return string.Format("Student: AppDomainName: {0}, {1} \n\nCourse: {2}",
// AppDomain.CurrentDomain.FriendlyName,
// studentName, studentCourse.ToString());
//}

public override string ToString()
{
return string.Format("Student: AppDomainName: {0}, {1} \n\nCourse: {2}",
AppDomain.CurrentDomain.FriendlyName,
studentName, studentDegree.ToString());
}

public Degree studentDegree { get; set; }

public void setCourse(Course course)
{
this.studentCourse = course;
studentCourse.CourseId = 2;
studentCourse.CourseName = "Updated Course";
}
}

In the above code we have introduced a new property studentDegree. We are instantiating it in the constructor. We have also updated the definition of ToString() to verify our discussion.

Let's use this in our form as follows:

private void btnDegree_Click(object sender, RoutedEventArgs e)
{
AppDomain appDomain = AppDomain.CreateDomain("MyAppDomain");

Student student = (Student)appDomain.CreateInstanceAndUnwrap(
"OtherAssembly",
typeof(Student).FullName);

student.studentName = "Muhammad";

Degree degree = student.studentDegree;
MessageBox.Show(student.ToString());
}

As Degree does not inherit from MarshalByRefObject, it results in the following:



Now let us we update the definition of Degree and inherit it from MarshalByRefObject as follows:

public class Degree : MarshalByRefObject
{
public string DegreeName { get; set; }
}

It results in the following message box:



Reverse Remoting:
First of , this is not a standard term but I thought it is a good name for this discussion. The idea is to discuss what happens behind the scene when we pass object references to a proxy either through method invocation or property assignment.

Method Invocation on Student Object's proxy:

Course course = new Course();
student.setCourse(course);

Reference assignment to Proxy's properties:

Course course = new Course();
student.studentCourse = course;

In both cases below, the runtime would create a proxy for Course object in the current domain and pass it to the Student object which is instantiated in the other domain. Let's see what this has been resulted in by showing the string representation of the student.
MessageBox.Show(student.ToString());

Since we have overloaded ToString() for Student. We see the following MessageBox.



It must be remembered that for both of these scenarios, the Course has to be inheriting MarshalByRefObject. Otherwise, it can be serializable if all we need is cloning the object rather than passing the reference. If Course wasn't inheriting from MarshalByRefObject, this would have resulted in exception like this:



Note:
Java has a similar technology called RMI. RMI stands for Remote Method Invocation. This works on the same idea of .net remoting.

Download:

Friday, January 14, 2011

WPF - Messaging using MSMQ

We have been discussing messaging options for intra and inter-process communication. Message Queuing is also a messaging infrastructure. The Microsoft product for Message queuing is MSMQ. There are various other products like JMS (Java Messaging Services), Apache’s Active MQ and TIBCO’s EMS which you might consider for enterprise messaging.



Types of Queues:
There are two types of queues supported in MSMQ. They are as follows:

1. Public Queues
2. Private Queues

Enabling MSMQ services in Windows:
Before we start using MSMQ we need to install MSMQ services on the machine we expect to keep queues.



Assembly and Namespace:
MSMQ types are in System.Messaging namespace. This is available in System.Messaging.dll. In order to use these types, we need to add a reference of this assembly.



Creating Queue:
We can create a MSMQ queue using Computer Management Console.



We can specify the name of queue. Let's name it WPFTestQueue:



We can also create queue through code as follows:

private void btnCreateQueue_Click(object sender, RoutedEventArgs e)
{
//Name of queue. Preceded by . (DOT) to specify local system
string queueName = @".\private$\WPFTestQueue";

MessageQueue messageQueue = null;
if (!MessageQueue.Exists(queueName))
{
messageQueue = MessageQueue.Create(queueName);
}
}

If a queue with same name already exists, it results in System.Messaging.MessageQueueException with exception message "A queue with the same path name already exists."



The queue, once created, can be found here:



Queuing Message:
It is very simple to queue messages in MSMQ. We just need to create an object of MessageQueue and send a message to the queue. The below code is an event handler for a button click event. It is demonstrating how we can send message to the queue.

private void btnSend_Click(object sender, RoutedEventArgs e)
{
MessageQueue queue = new MessageQueue(@".\private$\WPFTestQueue");
queue.Send(this.textBox1.Text);
}

Here . (DOT) refers to the local computer. As we send message to the queue, they become available for administration in Computer Management Console.



Various useful information about the message (including the message itself) can be found by taking the properties of the message in the same Window.



We can also see the body of message:



Receiving Message from the Queue:
To receive message from the queue, we just need to specify queue name including the complete path where the queue resides. We also need to specify the format of message. Here we are sending string message.

private void btnReceive_Click(object sender, RoutedEventArgs e)
{
MessageQueue queue = new MessageQueue(@".\private$\WPFTestQueue");
queue.Formatter = new XmlMessageFormatter(new Type[] {typeof(string)});
Message msg = queue.Receive();
this.textBoxMessage.Text = msg.Body.ToString();
}

We might need to share Interface definition between sender and receiver for message type if we are planning to send more complex messages.

It must be remembered that Receive is a synchronous / blocking call. You would be glad to know that MSMQ also has an asynchronous version of Receive. It is BeginReceive. It supports the specification of a callback which might be executed when the expected message is received.

private void btnASyncReceive_Click(object sender, RoutedEventArgs e)
{
MessageQueue queue = new MessageQueue(@".\private$\WPFTestQueue");
queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });

queue.BeginReceive(new TimeSpan(0, 0, 20), queue,
(IAsyncResult result) =>
{
Message message = ((MessageQueue)result.AsyncState).EndReceive(result); //queue.EndReceive(result);

this.Dispatcher.BeginInvoke(
new Action(
() =>
{
this.textBoxMessage.Text = message.Body.ToString();
}
), null);
}
);
}

Here we are using a timeout of 20 seconds. We passed the queue reference as stateObject in order to use it in the callback. By this way we are also avoiding the use of Captured variable from outside lambda. BeginReceive creates a ThreadPool thread. Since we are on a thread other than UI thread, we are using Dispatcher to copy the message to the interface. If the message is already available in the Queue, the callback would execute as soon as you call BeginReceive on the Queue.

You can use the attached project to send and receive message using MSMQ.



Taking advantage of Message Queuing Trigger Service:
MSMQ also allows us to execute an activity based on certain messages. We can peek / retrieve messages of interest and run those activities. These activities might be in the form a COM component method or an limited executable (*.exe) file.



Message Trigger Service is installed separately. You can see find that in Services.msc.




It allows you to define a set of triggers. Each trigger can have a set of rules. Each rule has conditions and associate actions.





For each message arriving to the queue, all rules in each trigger run. The trigger service should have associate (Peek, Retrieve rights on the message queue). A rule might have some conditions and an action associated.





Security & Trigger Service Account:
As apparent from the above image, Trigger Service in MSMQ 4.0 runs with Network Service account. It is required that you give Read and Execute on the Executable file.



The triggers also need to have permission so that messages can be peeked from the queue:



MSMQ Triggers service reports warning messages in the Event Viewer. The following is an example when the service could not find the executable file in the specified path.



We can also create custom view just for MSMQ related messages. In this example we are interested in messages from MSMQ and MSMQ Triggers services.



These messages would appear as follows:



Limitations for Executable file:

Being a service, MSMQ Triggers can not launch an executable which have user interaction. It seems any executable with Message loop is forbidden. This is true even when services are marked as Interactive Services. This is to avoid Shatter Attack.

http://en.wikipedia.org/wiki/Shatter_attack

This is just a forbidden tree to even mention about User interaction in Windows Vista and up. In Interactive Services MSDN mentions: Services cannot directly interact with a user as of Windows Vista. In Windows XP, it loads the application process but it doesn't bring the UI up (still shows splash screen when application is being loaded). You can verify that the application is loaded using Task Manager.

http://msdn.microsoft.com/en-us/library/ms683502%28VS.85%29.aspx

Note:
Public queues are used in a domain environment.

Download:

Tuesday, January 11, 2011

WPF - StringFormat when View's Non-String Properties use Binding

StringFormat was a useful addition to WPF Binding system. It provided fast and easy means of formatting the bound properties. There are still some issues with using StringFormat. I have discussed one issue and its workaround here:

StringFormat avoiding Current UI culture by default:

http://shujaatsiddiqi.blogspot.com/2010/08/wpf-localization-stringformat-for.html

In this post, we will be discussing the issue with StringFormat when bound with a property which is not a String type property. We will be binding the properties of our DataContext to the view and see different alternatives for formatting the data in shown in the Label control. You can get an idea of the issues from this image.



The view model has properties Id and Name which we will be binding to the view. To supports change notification, it is implementing INotifyPropertyChanged. The definition of the view model is as follows:

class StudentViewModel : INotifyPropertyChanged
{
private string _name;
private int _id;

public StudentViewModel()
{
Name = "Muhammad";
Id = 1;
}

public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged("Name");
}
}

public int Id
{
get { return _id; }
set
{
_id = value;
OnPropertyChanged("Id");
}
}

#region INotifyPropertyChanged Implementation

public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

#endregion INotifyPropertyChanged Implementation
}

In the constructor, we are assigning some definite values to Id and Name properties of the view model so that we don't have to worry about creating a Model.

The view using the above view model is as follows. This is the exact definition of image you have seen above. We have used various ways to format the string bound with the Content property of Label.

<Window x:Class="WpfApplication_MultiBinding_Object.StudentView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication_MultiBinding_Object"
Title="Student View" Height="384" Width="300">
<Window.Resources>
<local:StudentConverter x:Key="studentConverter" />
<local:StudentSingleBindingConverter x:Key="studentSingleBindingConverter" />
</Window.Resources>
<Window.DataContext>
<local:StudentViewModel />
</Window.DataContext>
<Grid>
<!--Single Binding with StringFormat-->
<Label Background="BlanchedAlmond"
Height="34" HorizontalAlignment="Left" Margin="13,18,0,0" Name="labelBoundStringFormat"
VerticalAlignment="Top" Width="246" >
<Label.Content>
<Binding Path="Name" StringFormat="test: {0}" />
</Label.Content>
</Label>
<!--Single Binding with ContentStringFormat-->
<Label Height="34" HorizontalAlignment="Left" Margin="12,58,0,0" Background="BlanchedAlmond"
Name="labelBoundContentStringFormat" VerticalAlignment="Top" Width="246"
ContentStringFormat="test: {0}" >
<Label.Content>
<Binding Path="Name" />
</Label.Content>
</Label>
<!--Single Binding with Converter-->
<Label Background="BlanchedAlmond"
Height="34" HorizontalAlignment="Left"
Margin="14,96,0,0" Name="label3" VerticalAlignment="Top" Width="246" >
<Label.Content>
<Binding Path="Name" Converter="{StaticResource studentSingleBindingConverter}" />
</Label.Content>
</Label>
<!--MultiBinding with StringFormat-->
<Label Background="BlanchedAlmond"
Height="34" HorizontalAlignment="Left" Margin="12,136,0,0" Name="label1"
VerticalAlignment="Top" Width="246" >
<Label.Content>
<MultiBinding StringFormat="{}{0} : {1}">
<Binding Path="Id" />
<Binding Path="Name" />
</MultiBinding>
</Label.Content>
</Label>
<!--MultiBinding with StringFormat and ContentStringFormat-->
<Label Background="BlanchedAlmond" Height="34" HorizontalAlignment="Left" Margin="12,174,0,0"
Name="label2" VerticalAlignment="Top" Width="246" ContentStringFormat="{}{0} : {1}">
<Label.Content>
<MultiBinding StringFormat="{}{0} : {1}">
<Binding Path="Id" />
<Binding Path="Name" />
</MultiBinding>
</Label.Content>
</Label>
<!--MultiBinding with Converter-->
<Label Height="33" HorizontalAlignment="Left" Margin="12,214,0,0" Background="Turquoise"
Name="labelBoundUsingConverter" VerticalAlignment="Top" Width="250" >
<Label.Content>
<MultiBinding Converter="{StaticResource studentConverter}">
<Binding Path="Id" />
<Binding Path="Name" />
</MultiBinding>
</Label.Content>
</Label>
<!--TextBlock MultiBinding with StringFormat-->
<TextBlock Height="33" HorizontalAlignment="Left" Margin="13,253,0,0" Name="textBlock1"
VerticalAlignment="Top" Width="247" Background="Azure" >
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} : {1}">
<Binding Path="Id" />
<Binding Path="Name" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<!--<Button Content="Button" Height="31" HorizontalAlignment="Left" Margin="11,296,0,0" Name="button1" VerticalAlignment="Top" Width="122" Click="button1_Click" />-->
</Grid>
</Window>

You can see that StringFormat has not fulfilled its responsibility of formatting the bound data. As a workaround we can use ContentStringFormat property of Label control and we can specify the format. This works perfectly fine but it never works with MultiBinding. If you see the image, you can verify that StringFormat is working perfectly fine when bound with Text property of TextBlock (property of type string).

The code behind of the above view is as follows:

public partial class StudentView : Window
{
public StudentView()
{
InitializeComponent();
}
}

As an alternate, you can see that the data is correctly formatted when converters are used. The definition of the XAML above has used two such converters. IMultiValueConverter is used for MultiBinding. The definition of IMultiValueConverterbased converter is as follows:

class StudentConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
string Id = values[0].ToString();
string Name = (string) values[1];
return string.Format("{0} : {1}", Id, Name);
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}

The definition of IValueConverter based converter used in the XAML definition of the view is as follows:

class StudentSingleBindingConverter : IValueConverter
{

public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
return string.Format("test: {0}", (string) value);
}

public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}

As you can see that it is just formatting the data in the same fashion as StringFormat is supposed to work but hasn't worked.

There is one more example you can look at for the same issue. In this example, I have to use a Converter to bind to CommandParameter when it is being Multiple bound with values in the form.

http://shujaatsiddiqi.blogspot.com/2011/01/updatesourcetrigger-explicit-for-mvvm.html

Download:

Monday, January 10, 2011

UpdateSourceTrigger = "Explicit" for MVVM Puritans

Recently, a new term has been evolved and established in WPF community. This is Pure MVVM. MVVM puritans is a belief system in MVVM. The believers of this faith have clean heart and no code behind :)

There are so many techniques developed by WPF community to adjust the believer of this faith in our society. One limitation that I have seen these people experiencing, is how to practice their religion with Explicit Binding. Just to recall, you can see this from msdn:

http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger.aspx

With explicit binding, this has always been expected to update the binding source using BindingExpression. You might be familiar with this code:

private void SubmitButtonClick(object sender, RoutedEventArgs e)
{
textBoxName.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}

But the thing is that this code is written in code behind which is not allowed under pure MVVM methodology. In this post, we are going to look at one technique which could be used to overcome such situation. We will be using CommandParameters for our DelegateCommand in the DataContext (ViewModels) of our View.

Let's assume a sample view, StudentView. This form has two fields. They are student's First and Last names. This view should also have a button to update the Student details to the view model. The organization has zero tolerance to code behind so it is part of design requirement to avoid it.



We would be using RelayCommand for this post. You can get the code of RelayCommand from Josh Smith's article:

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

The XAML definition of Student view is as follows:

<Window x:Class="WpfAppMVVM_Puritans_ExplicitBinding.StudentView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfAppMVVM_Puritans_ExplicitBinding"
Title="StudentView" Height="300" Width="555">
<Window.Resources>
<local:StudentConverter x:Key="studentParameterConverter" />
</Window.Resources>
<Window.DataContext>
<local:StudentViewModel />
</Window.DataContext>
<Grid>
<Label Content="First Name" Height="32" HorizontalAlignment="Left" Margin="13,11,0,0" Name="label1" VerticalAlignment="Top" Width="127" />
<TextBox Height="32" HorizontalAlignment="Left" Margin="148,10,0,0" Name="textBoxFirstName" VerticalAlignment="Top" Width="349" >
<TextBox.Text>
<Binding Path="FirstName" UpdateSourceTrigger="Explicit" />
</TextBox.Text>
</TextBox>
<Label Content="Last Name" Height="32" HorizontalAlignment="Left" Margin="13,49,0,0" Name="label2" VerticalAlignment="Top" Width="127" />
<TextBox Height="32" HorizontalAlignment="Left" Margin="148,48,0,0" Name="textBoxLastName" VerticalAlignment="Top" Width="349" >
<TextBox.Text>
<Binding Path="LastName" UpdateSourceTrigger="Explicit" />
</TextBox.Text>
</TextBox>
<Button Content="Save" Height="30" HorizontalAlignment="Left" Margin="148,86,0,0" Name="button1" VerticalAlignment="Top" Width="153"
Command="{Binding SaveCommand}" >
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource studentParameterConverter}">
<Binding ElementName="textBoxFirstName" Path="Text" />
<Binding ElementName="textBoxLastName" Path="Text" />
</MultiBinding>
</Button.CommandParameter>
</Button>
</Grid>
</Window>

As you can see the above view has two text boxes. The Text property of these text boxes are bound to FirstName and LastName property of the DataContext. Please notice UpdateSourceTrigger = Explicit with binding. An instance of StudentViewModel has been created and assigned as DataContext of this view. This also has a Update button. StudentViewModel is expected to have a command SaveCommand bound with the Command property of the button.

The most interesting thing and the reason of this post is the CommandParameter for the button. The CommandParameter has been bound with the Text properties of the two text boxes. We have to use MultiBinding for this. In order to get the value of this binding, we have to use converter. We have instantiate StudentConverter in the Resources section of the Window and used this as a StaticResource for this. Alternatively, We could have used StringFormat but WPF has this issue of StringFormat when bound to the property of System.Object type. StringFormat mainly works with string based properties for MultiBinding.

The definition of StudentViewModel is as follows:

class StudentViewModel : INotifyPropertyChanged
{
#region Private Fields
private string _firstName;
private string _lastName;
#endregion

#region Public Properties
public string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
OnPropertyChanged("FirstName");
}
}

public string LastName
{
get { return _lastName; }
set
{
_lastName = value;
OnPropertyChanged("LastName");
}
}
#endregion

#region Commands
RelayCommand _saveCommand;
public ICommand SaveCommand
{
get
{
if (_saveCommand == null)
{
_saveCommand = new RelayCommand((param) => this.Save(param),
param => this.CanSave);
}
return _saveCommand;
}
}

public void Save(object parameter)
{
string[] Names = ((string)parameter).Split(new char[] { ':' });
FirstName = Names[0];
LastName = Names[1];
}

bool CanSave
{
get
{
return true;
}
}
#endregion Commands

#region INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion INotifyPropertyChanged implementation
}

As expected by StudentView. It has two properties FirstName and LastName. It also has a RelayCommand based property SaveCommand. The view model is implementing INotifyPropertyChanged to propagate change notifications to the view.

Please notice the definition of Execute method of SaveCommand (named Save). This is expecting FirstName and LastName joined together using colon ":". This code is just splitting the two from parameter (passed through CommandParameter) and assigning to FirstName and LastName properties. It is also possible that these values are not assigned directly but they are updated before being assigned. Whatever you would assign to the property bound to the view, the changes will be propagated to the view because of implementation of INotifyPropertyChanged.

As seen from above, the responsibility of CommandParameter's converter is to combine first and last name with a colon. The definition of converter is as follows:

public class StudentConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string firstName = (string)values[0];
string lastName = (string)values[1];

return string.Format("{0}:{1}", firstName, lastName);
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}

Now run the application. Enter first and last names in the assigned textboxes and click Save button. Those values will be converted and passed to the SaveCommand in the view model. Here the view model's properties will be updated and changes are propagated to the View.


Download: