Posts tagged ‘C#’

May 22, 2012

Using Task for responsive UI in WPF

Blocking of the UI thread in a WPF application causes the application to become unresponsive. It is a common problem with several solutions, but usage of Task is in my opinion the most elegant solution because of readability and code brevity.
For this example we have a simple WPF application with a button that starts a long running loop. A busy indicator is displayed while the loop is running.

_busyIndicator.IsBusy = true;

for (var i = 0; i < 100; i++)
{
  System.Threading.Thread.Sleep(50);
}

_busyIndicator.IsBusy = false;

As written, this code will freeze the app for the duration of the loop since it blocks execution of the UI thread. The solution is to run the loop Asynchronously and using Task is the easiest way to accomplish it in this case.

_busyIndicator.IsBusy = true;

var T = new Task(() =>
{
  for (var i = 0; i < 100; i++)
  {
    System.Threading.Thread.Sleep(50);
  }
});

T.Start();

_busyIndicator.IsBusy = false;

However, this bit of code will crash the application because we have not passed control back to the context of the UI thread. The ‘Task.ContinueWith’ method can be used to serve that purpose.

var T = new Task(() =>
{
  for (var i = 0; i < 100; i++)
  {
    System.Threading.Thread.Sleep(50);
  }
});

T.ContinueWith(antecedent => _busyIndicator.IsBusy = false, TaskScheduler.FromCurrentSynchronizationContext());

Running the application will now result in complete responsiveness. You can move, resize, or perform other operations while the loop is running. However, there are cases where CPU intensive loops may cause the busy indicator to not be displayed. In WPF, the UI render events are queued to prevent issues related to multiple execution of the same event. To prevent this, we want to make sure that the busy indicator is displayed. And for that we can use a timer event.

private System.Windows.Threading.DispatcherTimer _timer = null;
public MainWindow()
{
  InitializeComponent();
  _timer = new DispatcherTimer();
  _timer.IsEnabled = false;
  _timer.Tick += new System.EventHandler(RunTask);
}

private void StartProcess(object sender, RoutedEventArgs e)
{
  _busyIndicator.IsBusy = true;
  _timer.Interval = new TimeSpan(0,0,0,0,100);
  _timer.Start();
  // go back to the user thread, giving the busy indicator a chance to come up before the next timer tick event
}

void RunTask(object sender, System.EventArgs e)
{
  _timer.IsEnabled = false;

  var T = new Task(() =>
  {
    for (var i = 0; i < 100; i++)
    {
      System.Threading.Thread.Sleep(50);
    }
  });

  T.ContinueWith(antecedent => _busyIndicator.IsBusy = false, TaskScheduler.FromCurrentSynchronizationContext());
  T.Start();
}

So, when the user clicks the button, the busy indicator is set to true first, the timer is started, and once it has ticked the Task is called. Using the timer event in this manner ensures that the loop will not be executed until the busy indicator is rendered.

The complete source code for this example can be found in our github repository.

Advertisements
Tags: ,
January 11, 2012

Homegrown Dynamic IP Tracking

I often need to remotely access my home computer. Since dynamic DNS services are not always available to me, I needed a way to be notified when my ISP issued a new IP address. The first task was to choose one of the many services that happily provide your public address. The ideal candidate would be one that gives a relatively easy to parse response. After a bit of searching, I found that the nice folks over at http://dyndns.org offer just that with http://checkip.dyndns.org

The .Net WebClient provides an easy means to retrieve the response:

var client = new WebClient();
var response = client.DownloadString("http://checkip.dyndns.org");

After a bit of simple parsing, we have our public IP address:

const string startToken = "Current IP Address: ";
var startIndex = response.IndexOf(startToken);
startIndex += startToken.Length;
var endIndex = response.IndexOf("&lt;/body&gt;");
var ip = response.Substring(startIndex, endIndex - startIndex);

Now that we have the public IP address, notification becomes a task for the .Net SmtpClient. Using email as the notification method certainly isn’t the only solution, but has the benefit of being private. For this particular project, I’m using an App.config to populate properties of the SmtpClient.

var appSettings = ConfigurationManager.AppSettings;
var email = Convert.ToString(appSettings["EmailAddress"]);
var displayName = Convert.ToString(appSettings["DisplayName"]);
var fromAddress = new MailAddress(email, displayName);
var toAddress = new MailAddress(email, displayName);
var fromPassword = Convert.ToString(appSettings["EmailPassword"]);
var smtp = new SmtpClient
            {
                Host = Convert.ToString(appSettings["EmailHost"]),
                Port = Convert.ToInt32(appSettings["EmailPort"]),
                EnableSsl = Convert.ToBoolean(appSettings["EnableSsl"]),
                DeliveryMethod = SmtpDeliveryMethod.Network,
                UseDefaultCredentials = false,
                Credentials = new NetworkCredential(fromAddress.Address, fromPassword)</p>
            };

And now, sending the message is simply a matter of constructing a .Net MailMessage and passing it to the SmtpClient Send method.

var subject = "Current Home IP Address: " + ip;
var body = subject;
using (var message = new MailMessage(fromAddress, toAddress)
{
    Subject = subject,
    Body = body
})
{
    smtp.Send(message);
}

It is certainly feasible to schedule a daily task for this to run, but I decided to wrap it into a service so notification emails are only sent if the public IP changes. The entire project can be found in our brand new github repository linked below.

https://github.com/yojimbocorp/blog-posts

January 2, 2012

How to get the value of a custom attribute in C#

In a recent project, I needed to get the value of a custom attribute that was set on various class properties. More precisely, the custom attribute was a string that needed to be evaluated programmatically to see if it matched a given value. This particular case came up during unit testing of localized strings in a web application, but may be applicable to a wide variety of use cases involving custom attributes.

In this example, there is a class that sets a custom attribute like this:

public class UserAccount
{
    [LocalizedDisplayName(&quot;SOME_RESOURCE_ID&quot;)]
    public string UserAccountName { get; set; }
    ...
}

This attribute is referenced throughout the application to display the correct text for the current culture, but the problem is that there is no inherent mechanism to get the actual string value of the resource associated with the given class property for testing purposes. The solution was to create a utility method which does just that:

public static object GetAttributeValue(Type objectType, string propertyName, Type attributeType,

string attributePropertyName)
{
    var propertyInfo = objectType.GetProperty(propertyName);
    if (propertyInfo != null)
    {
        if (Attribute.IsDefined(propertyInfo, attributeType))
        {
            var attributeInstance = Attribute.GetCustomAttribute(propertyInfo, attributeType);
            if (attributeInstance != null)
            {
                foreach (PropertyInfo info in attributeType.GetProperties())
                {
                    if (info.CanRead &amp;&amp;
                      String.Compare(info.Name, attributePropertyName,
                      StringComparison.InvariantCultureIgnoreCase) == 0)
                    {
                        return info.GetValue(attributeInstance, null);
                    }
                }
            }
        }
    }
    return null;
}

This method is in an AttributeUtil class. An example call to the method looks like this:

var value = AttributeUtil.GetAttributeValue(typeof(UserAccount), &quot;UserAccountId&quot;,
                                             typeof(LocalizedDisplayNameAttribute),&quot;DisplayName&quot;);

It was surprisingly hard to find relevant information for this particular problem, so I hope you found this useful. A complete example project is available in our codeplex repository.

GetAttributeValue

As an exercise to the reader, you may choose to package GetAttributeValue as an extension method on the Attribute class itself. Also, beware that this will not work against attributes whose value is an array type, because we’re passing NULL as the second parameter to PropertyInfo.GetValue method.

Tags:
December 27, 2011

How to Show the Silverlight Busy Indicator When Your Task Has to Run on the UI Thread

Warning: this is a “hack” to be used when all other options have been exhausted

Recently, I was working on a project that required me to implement export to Excel from a third-party grid. The task was quite simple as the grid control already had a method for the purpose of creating a workbook. However, when using the method from a button click handler my entire UI would freeze for the duration of the export. The export had to be performed on the UI thread, because it relied on a method located on the control (which in turn touched other properties of the control). I knew I couldn’t get around the freeze, but wanted to display a busy indicator. After searching the web I failed to find a solution. The issue is that the busy indicator itself has to use the UI thread to begin animating and Silverlight queues user interface updates (to improve performance), so just because you set the ‘IsBusy’ property true, you’re not guaranteed that the user has seen the indicator.

I had some work to do before kicking off the export and was already spawning a background thread via the method ThreadPool.QueueUserWorkItem.

However, the only way to get the busy indicator to display was to add a Sleep operation as the first step of my thread and I wasn’t sure how long I needed to sleep before I had some indication that the busy indicator has displayed.

My final workaround consisted of the following steps:

1)      Implement the LayoutUpdated event on the BusyIndicator instance. Inside this event, I set a private bool field to true. The field is marked as volatile to prevent compiler optimizations which sometimes cause multiple threads to see a different value (the alternative would have been to use another field and lock on it when touching the bool).

2)      In my button click event, I set the private field to false anytime I set the ‘IsBusy’ property of the busy indicator to true.

3)      I then added this code block at the top of my background task (basically waiting for the busy indicator to update its layout – i.e. display itself) before doing any other work:

while (!_hasBusyIndicatorUpdatedLayout)
{
         Thread.Sleep(100);
}

After exiting this while loop, I kicked off the call to process my Excel export on the UI thread.

There are a couple of issues with this solution:

1)      It’s a hack

2)      The busy indicator’s animation will be frozen (along with the entire application)

However, the alternative was to have a frozen UI all around. I am attaching a sample project implementing all of the above. If you want to see what happens without the check, just comment out the ‘while’ loop shown above.

If anyone has come up with a more elegant solution or improves upon this, please comment below.

The complate click handler looks like this:

private void ButtonClick(object sender, RoutedEventArgs e)
{
    SetBusy("Exporting data...");

    ThreadPool.QueueUserWorkItem((state) => 
    {
        // this is how we check if the busy indicator has 
        // started to display to the user
        while (!_hasBusyIndicatorUpdatedLayout)
        {
            Thread.Sleep(100);
        }

        // now we can perform our busy task
        DoBusyWorkOnUiThread();
        RemoveBusy();
    });
}

Download the project below for the full implementation. If you comment out the line in the constructor that does this:

busyIndicator.LayoutUpdated += BusyIndicatorLayoutUpdated;

You will see that the busy indicator no longer displays.

Download Project

Tags: , ,
December 3, 2010

What is the most popular programming language?

This web site seems to be doing a decent job of gathering various statistics from which one can infer popularity:

http://www.langpop.com/

I’d like to believe that C# is the most popular language, but apparently Java ranks higher on most counts. In my opinion many more advances have been made in the .NET platform than the various java based platforms. My guess is much of the popularity is due to the dominance of java when it comes to mobile development (not counting the huge number of Objective-C based apps on the iPhone).

A friend of mine also noted the prevalence of Java in introductory computer science course.

Finally, another friend reminded me of Mark Twain’s quote:

“There are three kinds of lies: lies, damned lies, and statistics.”