Dienstag, 2. November 2010

Multithreading leicht gemacht...

Neulich ist mir eine sehr schlanke Metode bewusst geworden, mehere Aufgaben parallel anzustoßen und diese am Ende einer Methode wieder zu synchronisieren..

Ein Szenario dazu: in einer Methode möchte ich drei parallele Aufgaben anstoßen. Während diese laufen habe ich selber noch ein bisschen Arbeit zu erledigen. Am Ende der Methode brauche ich dann die Ergebnisse der parallelen Aktionen.

Die erste Idee dazu sind natürlich Threads. Also, wie war das nochmal... Thread-Objekt, da kommt ein ThreadStart (oder ParameterizedThreadStart) rein. Mh... der nimmt als Thread-Code aber nur ein Action-Delegate. Ich wollte aber eigenltich auch eine Funktion ausführen, oder eine Action mit mehreren Parametern. Kriegt man natürlich alles hin - Wrapper-Methoden, mehrere Parameter in eine einzelnes Objekt verpacken und so weiter. Unter dem Strich sind solche Lösungen aber immer etwas unhandlich.

Die weitaus einfachere Lösung basiert intern natürlich auch auf Threads. Diese erstelle ich aber nicht selber. Sondern ich nutze einfach das Async-Pattern. Silverlight-Entwicklern dürfte dieses Muster schon begegnet sein, weil alle Serviceaufrufe auf diesem Muster basieren. Einen ausgezeichneten Blogpost zum Thema gibt es hier.

Folgende Punkte am Async-Pattern sind für die Lösung interessant:
  1. Man benötigt ein Delegate für seine Methode. Das Delegate stellt die Methoden Begin- / EndInvoke bereit. Die Standard Func / Action Delegates dürften für die meisten Fälle ausreichen.
  2. Man muss BeginInvoke kein Callback übergeben, der Parameter darf null sein.
  3. Bei Verwendung generischer Action- / Func-Delegates verlangt die BeginInvoke-Methode typsichere Parameterwerte.
  4. EndInvoke ist eine blockierende Methode - falls noch kein Ergebnis vorliegt wartet die Methode solange bis das der Fall ist.
Besonders interessant sind aus meiner Sicht die Punkte 2 und 4 in Kombination.

Ein bisschen Code sagt mehr als tausend Worte, also:

class Program
  {
    static void Main(string[] args)
    {
      // Delegates holen
      Func<long> CountAFunc = CountA;
      Action<int> WriteCAction = WriteC;

      // Asynchron aufrufen - keine Callbacks, wir wollen die Ergebnisse gleich hier haben.
      IAsyncResult CountAAsyncResult = CountAFunc.BeginInvoke(null, null);
      IAsyncResult WriteCAsyncResult = WriteCAction.BeginInvoke(100, null, null);

      // Selber was arbeiten
      Thread.Sleep(10 * 1000);

      // Auf asynchrone Ergebnisse warten - EndInvoke ist blockierend!
      long CountAResult = CountAFunc.EndInvoke(CountAAsyncResult);
      WriteCAction.EndInvoke(WriteCAsyncResult);

      // Ergebnisse ausgeben
      Console.WriteLine("CountAResult " + CountAResult);
      Console.ReadLine();
    }

    public static long CountA()
    {
      long Result = 0;

      for (int i = 0; i < 1000; i++)
      {
        Result += i;
        Console.WriteLine("A " + i);
        Thread.Sleep(10);
      }

      return Result;
    }

    public static void WriteC(int Start)
    {
      for (int i = Start; i < 1000; i++)
      {
        Console.WriteLine("C " + i);
        Thread.Sleep(10);
      }

    }
  }


Ich habe zweieinfache Methoden die asynchron ausgeführt werden sollen: CountA und WriteC. Erstere ist eine parameterlose Function die (umständlich) die Summe der Zahlen von 1 - 999 berechnet. Die zweite Zählt von einem Startwert bis 1000. Beide Methoden erzeugen noch eine Ausgabe auf der Konsole.

Zu den beiden Methoden beschafft man sich Delegates, ruft diese mit BeginInvoke auf. Dann erledigt man seine eigene Arbeit (hier einfach 10 sek. warten). Dann sammelt man mit EndInvoke auf den Delegates die tatsächlichen Ergebnisse ein und gibt diese aus.

Mulitthreading leicht gemacht! Mehr zum Thema gibt es in der MSDN.

Viel Spaß!

Freitag, 29. Oktober 2010

Ungültige oder nicht wohlgeformte Anwendung. Überprüfen Sie das Manifest.

Vielleicht ist der ein oder andere schon mal über den Silverlight Fehler

Ungültige oder nicht wohlgeformte Anwendung. Überprüfen Sie das Manifest.
oder in englisch
Invalid or malformed application: Check manifest.
gestolpert.

 
Im Netz gibt es lange Threads mit verschiedenen Lösungen für das Problem. Hier die Lösungen die mir kürzlich geholfen hat:

 
  • Wir haben in unseren SL-Projekten den Namespace der App.xaml.cs geändert, und die Änderung freilich auch in der App.xaml im x:Class Attribut nachgezogen. Vergessen hatten wir in den Eigenschaften des Silverlight Projekts auf der Seite "Silverlight" unter "Startup Object" auch das "neue" App-Objekt eingetragen. Daher der Fehler. Bei korrekter Einstellung geht alles wieder.
  • Nach der Fehlermeldung "Xap packaing failed: OutOfMemoryException" kommt der Fehler auch. In diesem Fall wählt man im Studio nicht "Rebuild Solution" (was ich normalerweise tue) sondern "Build Solution" - sobald man erfolgreich kompilieren konnte ist der Fehler weg.

 
Es gibt noch andere Ursachen für das Problem und dazu natürlich auch andere Lösungen - diese können gerne als Kommentar hinterlassen werden :-)

Dienstag, 5. Oktober 2010

Silverlight: Properties die in einem Style gesetzt werden sind statisch

Ein Sache die eigentlich offensichtlich ist, hat mich heute überraschend getroffen:

Properties die man innerhalb eines Silverlight Custom Control per <setter> setzt, sind statisch und alle Instanzen dieses Controls teilen sich die gleiche Instanz für den Property-Inhalt.

Nach kurzem suchen in der MSDN wurde deutlich dass das auch das erwartete Verhalten ist:

"Contains property setters that can be shared between instances of a type." [1]

Folgendes Szenario:
Ich wollte ein ContontControl schreiben, das ein Control enthält und eine IsDirty-Property bereitstellt. Wird IsDirty auf true gesetzt, soll sich das enthaltene Control entsprechend ändern, z.B. indem der Text jetzt in rot dargestellt wird. Es sollte die Möglichkeit bestehen dass eine TextBox im Dirty-State anders aussieht als z.B. eine Textbox.
Zu diesem Zewck habe ich eine kleine ResourceSelector Komponente geschrieben, die aufgrund des Typnamens des enthaltenen Controls ein Storyboard auswählt und dieses auf das enthaltene Control anwendet. Auf diese Weise kann man für jedes Control einen eigenen Dirty-Style definieren.
Meinem DirtyContainer-Control habe ich dann eine Property StoryboardSelector spendiert, die eine Instanz von meinem ResourceSelector aufnehmen kann.

Das führt zu folgendem Markup:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
  xmlns:Local="clr-namespace:Silverlight.Controls"
  >

  <Style TargetType="Local:DirtyContainer">
    
    <Setter Property="StoryboardSelector">
      <Setter.Value>
        <Local:ResourceSelector>
          <Local:ResourceSelector.Resources>
            <ResourceDictionary>
              <Storyboard x:Key="TextBox" >
                ...
              </Storyboard>

              <Storyboard x:Key="ComboBox">
                ...
              </Storyboard>

              <Storyboard x:Key="CheckBox">
                ...
              </Storyboard>
            </ResourceDictionary>
          </Local:ResourceSelector.Resources>
        </Local:ResourceSelector>
      </Setter.Value>
    </Setter>
    
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="Local:DirtyContainer">
          <Grid>
            <ContentControl x:Name="Content" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"
                HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
                                            Padding="1">

            </ContentControl>
          </Grid>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</ResourceDictionary>

Wenn sich nun die IsDirty-Eigenschaft von meinem DirtyContainer ändert, suche ich in dem StoryboardSelector nach einem passenden Storyboard basierend auf dem Typnamen (m_Content ist die Instanz des ContentControls aus dem Template):

StoryboardSelector.ResourceSwitch = m_Content.Content.GetType().Name;
DirtyStoryboard = StoryboardSelector.CurrentResource as Storyboard;

Storyboard.SetTarget(DirtyStoryboard, m_Content.Content as DependencyObject);
DirtyStoryboard.Begin();

Geknallt hat es dann in Zeile 3, wenn man zweimal eine Combobox in der Applikation verändert hat:


Der Vorgang ist auf einer aktiven Animation oder einem aktiven Storyboard nicht gültig.
Das Stammstoryboard muss zunächst angehalten werden.


Diese Fehlermeldung ist dem Umstand geschuldet, dass jetzt alle Comboboxen das gleiche Storyboard verwenden, aber eine Storyboard-Instanz immer nur ein Target haben darf.

So weit, so gut, das verstehe ich alles. Aber ich suche eine Lösung bei der ich bereits im Control-Style einen Standard für die Storyboards setzen kann. Derzeit habe ich den ganzen ResourceSelector in die Resources-Auflistung des ContentControls geschoben und hole mir die Instanz im OnApplyTemplate:

StoryboardSelector = m_Content.Resources["ResourceSelector"] as ResourceSelector;



Keine wirklich tolle Lösung - für bessere Ideen bin ich jederzeit offen...

Freitag, 24. September 2010

MVVM with WPF and Silverlight

Thanks to everybody who attended to my BASTA talk. I hope you enjoyed the session as much as I did. As promised I provide you with a download of the final stage of the last demo (which should include all the stuff that we have done) and the slides.

If you think that anything is missing or you have any question, do not hesitate to leave a comment or to contact me otherwise.

Have fun with MVVM!

Mittwoch, 8. September 2010

SlSvcUtil does not generate code in Silverlight 4

I had a weired error today. We generate some of our Silverlight proxies using batch files calling slsvcutil (C:\Program Files\Microsoft SDKs\Silverlight\vX.0\tools). With Silverlight 3 everything was fine. After switching to Silverlight 4 the tool stopped generating code without any comment.

Found the solution here.

Simply put a SlSvcUtil.exe.config side by side with the exe with the following content:


<configuration>
  <satelliteassemblies>
    <assembly name="SlSvcUtil, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  </satelliteassemblies>
</configuration>

And immediately it works like a charm!

Have fun!

Donnerstag, 5. August 2010

null value kills the binding

A short one this time: I am working on a silverlight project. Actually it spent several hours to find a simple truth:

If a property that is involved in a binding retruns null, the binding is dead.

That means that if the propery value changes later on and you raise a PropertyChanged event, your view will not get updated, because for any reason the binding engine does not call the properties getter any more.

Perhaps that saves some of you some valuable lifetime.


Freitag, 2. Juli 2010

A slim reflection API to get / set property values

I am working with a datagrid that consumes dynmaic data. Due to the fact that Silverlight does not provide that functionallity I used the example of Vladimir Enchev from Telerik.

That leads to the fact that I dont know the type of the objects my grid is bound to at compile time, becuase the type is dynamically generated at runtime. I have the scenario that the user clicks to "Edit current entry", then a new dialog opens showing the details for the item selected within the grid. What I needed was a method that gives me the Value of the primary key field of this object.

To avoid writing reflection code every time, I intruduced two extender called GetPropertyValue and SetPropertyValue.

First of all I need to be able to get a PropertyInfo object from a given Property path. I wanted to support multi level pathes (such Person.Address.ZipCode). Indexed properties are not supported.

The code to retrieve the PropertyInfo is recursive. As long as the path contains a "." I get the value of the head property using GetPropertyValue extender and then get the next property for the rest paht using a recursive call to GetProperty:


public static PropertyInfo GetProperty(this object target, string path)
        {
            if ((target == null) || string.IsNullOrEmpty(path))
            {
                return null;
            }

            String CurrentPath = String.Empty;

            if (path.Contains('.'))
            {
                String[] pathParts = path.Split(new char[] { '.' });
                String restPath = path.StripLeft(pathParts[0].Length + 1);
                CurrentPath = pathParts[0];

                return target.GetPropertyValue<Object>(CurrentPath).GetProperty(restPath);
            }

            PropertyInfo property = target.GetType().GetProperty(path, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            return property;
        }

        public static T GetPropertyValue<T>(this object target, string path)
        {
            PropertyInfo property = target.GetProperty(path);
            if (property == null)
            {
                return default(T);
            }

            try
            {
                return property.GetValue(target, null).To<T>(default(T));
            }
            catch
            {
                return default(T);
            }
        }

Using if (path.Contains('.')) I check wether I need to make a recursive call. If so, the path is split up by the '.'. I then take the head of the path and the rest path. Then I do the recursive call:

return target.GetPropertyValue<Object>(CurrentPath).GetProperty(restPath);

If there is no dot in the path left I get the PropertyInfo using GetType().GetPropert(path). It was important to me to get the Property using a case invariant path, so 'Name' and 'NAME' should both retrieve the 'Name' property, so I had to provide the correct binding flags.

The GetPropertyValue extender then just delivers the value of the property via the normal reflection api. To get the correct type I use the To() extender:

        public static T To<T>(this object Value, T DefaultValue)
        {
            try
            {
                // Check if target type is a nullable
                Type TypeOfT = typeof(T);
                if (TypeOfT.IsGenericType && TypeOfT.GetGenericTypeDefinition() == typeof(Nullable<>))
                { 
                    // Check if value is not a nullable type
                    Type TypeOfValue = Value.GetType();
                    if (!TypeOfValue.IsGenericType || !(TypeOfValue.GetGenericTypeDefinition() == typeof(Nullable<>)))
                    { 
                        // Target type is a nullable, but value type is not => cast the value to the nullables target type first
                        Type TypeOfNullable = TypeOfT.GetGenericArguments()[0];
                        Object ValueInTargetType = Convert.ChangeType(Value, TypeOfNullable, LanguageContext.DefaultInstance.Culture);

                        // Return converted value as Nullable<TypeOfValue>
                        return (T)ValueInTargetType;
                    }
                }

                // Either both types are nullable or neither types are nullable, so just convert them
                return (T)Convert.ChangeType(Value, typeof(T), LanguageContext.DefaultInstance.Culture);
            }
            catch (Exception ex)
            {
                return DefaultValue;
            }
        }

This code can handle the conversion of nullable types to its underlying type and vice versa as well.

Having this in place, SetPropertyValue is easy:

public static void SetPropertyValue<T>(this object target, string path, T value)
        {
            PropertyInfo property = target.GetProperty(path);
            if (property == null)
            {
                return;
            }

            try
            {
                property.SetValue(target, value, null);
            }
            catch
            {
                return;
            }
        }

Actually I am thinking about a small fluent reflection API that hides you from all the GetType() kind of stuff. I will blog about this another time.

Have fun!.

Donnerstag, 24. Juni 2010

Synchronizing multiple WCF Service Calls

The scenario is as follows: assume you have a service that delivers articles. It has two methods: GetArticleList, which returns a list of all articles, and GetSpecialOfferArticle which returns a special offer for a given month and year. You want to display the articles in a listbox and higlight the special offer. The point is, that within the client you first need to get the result of GetAllArticles and then the result of GetSpecialOfferArticle. When we do the service call asynchrounsly (like we must do in silverlight), the return order is not guaranteed.

So the article introduces a class called ServiceCallSynchornizer to handle the problem. The idea is to register multiple service calls, cache the results and get notified by an event once all calls are completed. The case described above would then look like:


private ServiceCallSynchronizer sync; 
private ArticleServiceClient proxy ;

private void DoServiceCalls()
{
  proxy = new ArticleServiceClient();
  sync = = new ServiceCallSynchronizer();

  sync.AllCompleted += new EventHandler<EventArgs>(sync_AllCompleted);
  sync.AddServiceCall(new Action<Object>(proxy.GetArticleListAsync), "ArticleList");
  sync.AddServiceCall(new Action<int, int, Object>(proxy.GetSpecialOfferArticleAsync), DateTime.Now.Month, DateTime.Now.Year, "SpecialOffer");
  
  sync.ExecuteAll();
}

private void sync_AllCompleted(object sender, EventArgs e)
{
  ObservableCollection<Article> articles = sync.GetResult<GetArticleListCompletedEventArgs>("ArticleList").Result;
  Article specialOffer = sync.GetResult<GetSpecialOfferArticleCompletedEventArgs>("SpecialOffer").Result;

  ArticleList.ItemsSource = articles;
  ArticleList.SelectedItem = (from art in articles where art.Number == specialOffer.Number select art).FirstOrDefault();
}

Within the DoServiceCalls method we register for the AllCompleted event of the ServiceCallSynchronizer. This event is called when all registered service calls are completed.
Service calls are added using the AddServiceCallMethod. We must pass a delegate into this method as well as the call paramters. This way, the method name and parameters are defined type safe and a check wether the method name exists or not can be done at compile time. The parameter values though are passed as Object[], so they are not type safe at design time, which is a little drawback. But the developer can see the needed parameters within the Action<> definition so it should be ok.
The last parameter passed into the AddServiceCall methods ("ArticleList" / "SpecialOffer" in the example above) are unique keys that we can use to identify the result of our service calls in the AllCompleted event handler. They are mapped to the UserState parameter of the underlying service proxy method.
The usage of this keys can be seen in the sync_AllCompleted method. Using the ServiceCallSynchonizers GetResult<T> method we can obtain the service result by passing in the appropriate key. Because we get notified when all calls are completed, I can use my results in the needed order.

The code can be found here. As usual provided as-is with no warrenties.

The provided solution might help you if you use WCF. If you are free to use other technologies you might choose the Microsoft CCR or the CodePlex project XCoordination Application Space. Ralf Westphal blogged about it and presents these alternatives in detail.

Have fun!

Dienstag, 22. Juni 2010

A tool to compare two WinDbg DumpHeap -stats outputs

As a Silverlight developer one of my favorite tools besides Visual Studio is WinDbg. The native debugger has an extension for silverlight that helps you find memory leaks by showing you why your objects stick in memory.

If you want to know more on how to use it, dont miss Tess Ferrandez's blog ("If broken it is, fix it you should"). Also helpful (and full of further links) was David Ansons blogpost.

One day I found that all the objects I was searching for have been removed from memory. I almost thought that it was donut time, but then I noticed that memory was still slightly increasing over time.

The sos-extension for WinDbg offers a command called !DumpHeap -stat which dumps out all the objects on the managed heap. To find my leak I decided to take a dump, do something with my app, take a second dump and then compare the two dumps to see which new objects had been created.

To be able to compare the two dumps effectivly I wrote a small tool. Simply copy the dump from WinDbg via <Ctrl>+C and click on the "Paste" button above the corresponding textbox. Pasting the text directly to the textbox using <Ctrl>+V did not work for me, the text was chopped of. Dont know why, so I added the copy button. As soon as you copy the second dump to the second window, the text input is converted into a joined dataset and the comparrison result is shown in the lower pane.

The tool also calculates the "increasement factor" and colorizes the new count green or red depending on wether the number of objects increased or decreased (or is the same).

You can download the code here. The code is provided "as is" with no warrenties. Have fun!

Donnerstag, 17. Juni 2010

A great MVVM view model base class for SL4 - Part II

In my previous post I mentioned the view model base class of Brian Genisio. It uses a dictinary as a value storage for your view models properties. In your view model you write the following:

public class MyViewModel : ViewModelBase
{
  public string Name
  {
    get { return Get(() => Name); }
    set { Set(() => Name, value); }
  }
}

The expression "() => Name" is used instead of the string "Name" to identify the property in a strong typed manner (that means you could have also written Get("Name") instead).

All this works fine as long as your view model orignially provides all the values you need. In my case I have view models that use model classes as data storage like so:

public class MyViewModel : ViewModelBase
{
  private Person m_Person;
  public string Name
  {
    get { return m_Person.Name; }
    set
    {
      if (m_Person.Name != value)
      {
        m_Person.Name = value;
        OnPropertyChanged("Name");
      }
    }
  }
}

That forces me to write all the set-code myself again. My idea to be able to use all the base class goodies again was to add an additional but optional business object to the base class as well as some new overloads to the Get / Set methods:

public class ViewModelBase : INotifyPropertyChanged
{
  private Object m_BusinessObject;

  public ViewModelBase() : this(null)
  { }

  public ViewModelBase(Object BusinessObject)
  {
  m_BusinessObject = BusinessObject;
  ...
  }

  protected T Get<TBusniessObject, T>(Expression<Func<T>> expression, T DefaultValue)
  {
    if (m_BusinessObject == null)
      return DefaultValue;

    String propName = GetPropertyName(expression);
    return (T)m_BusinessObject.GetType().GetProperty(propName).GetValue(m_BusinessObject, new object[] { });
  }

  protected void Set<TBusinessObject, T>(Expression<Func<T>> expression, T value)
  {
    if (m_BusinessObject == null)
      return;

    if (Get<TBusinessObject, T>(expression).Equals(value))
      return;

    String propName = GetPropertyName(expression);
    m_BusinessObject.GetType().GetProperty(propName).SetValue(m_BusinessObject, value, new object[] { });
    Set(propName, value);
  }

}


The idea is simple: as long as the business object is not null we get / set the value out of it via reflection. In the setter we first compare the current value with the acutal one to leave if nothing has changed. After having set the value to the business object, I pass the value through to the normal Set method in order to get all the other gadgets like dependent methods working.

With that code in place I am able to write the Property from my above example like so:

public class MyViewModel : ViewModelBase
{
  private Person m_Person;
  public string Name
  {
    get { Get<Person, string>(() => Name); }
    set { Set<Person, string>(() => Name, value); }
  }
}

Brians code is at codeplex. My suggestions can easily be incorporated.

Have fun.

A great MVVM view model base class for SL4

Brian Genisio blogged about a MVVM ViewModel base class with lots of fantastic features to save you from writing too much plumbing code. You can read about it in his blog:

My view model base
My view model base - Silverlight support

To me, this base class contains of two basic ideas.
  1. The first idea is that you do not need to write all those ICommand-type properties yourself but let them generate dynamically from methods that are named by the convention Execute_< commandname > / CanExecute_< commandname >. The properties are stored within a dictionary within the base class.
  2. The second idea is not to write all these OnPropertyChanged notification code all the time you publish a property in your view model, but let the base class do it. For this reason the base classes dictionary (the same on in which the ICommand-properties are stored) acts as a value storage for all your property values. Within your view model you only call a base class method to get and set the value. Therby all get /set code runs thorugh a central point that handles the OnPropertyChanged-stuff.

Up to Silverlight 3 there was a problem with data binding of these "dynamic" properties, because in contrast to WPF Silverlight was not able to bind against dictionaries. The workaround was to use a value converter to do the magic.

With Silverlight 4 it is possible to bind against indexers using the following syntax:


< button type="submit" command="{Binding" content="Click me" />

Note the square brackets around the command name - they indicate that the name inside the brackets is to be interpreted as the key of the indexer and yields to

MyViewModelInstance["ButtonClick"]

With this new feature in place, the value converter is no longer needed, which makes the code more readable.

Brian hosted all the sourcecode on codplex.

Thanks for sharing!