Archive for the ‘Winforms’ Category

Catching Thread Exceptions in C#

I have a Winforms app where I am performing asynchronous functions. I am using the delegate model and have threadsafe calls for updating my UI. My worker threads happen in an instance of another class, not the class that is the form.

I had the impression that the global Application.ThreadException event handler would catch exceptions that happened off on my working threads. This does not seem to be the case. The following code (as a console app) shows my problem and won’t catch the exception. The program executes as if nothing bad happened.

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.Remoting.Messaging;
using System.Threading;
 
namespace BadThreadException
{
    class Program
    {
        delegate void WorkerDelegate(int input);
 
        static void Main(string[] args)
        {
            Application.ThreadException += new ThreadExceptionEventHandler(App_ThreadException);
 
            Worker mult = new Worker();
 
            AsyncCallback callback = new AsyncCallback(Finished);
 
            WorkerDelegate threadedWork = new WorkerDelegate(mult.DoSomethingImpressive);
 
            threadedWork.BeginInvoke(9, callback, null);
 
            Console.ReadKey();
        }
 
        static void Finished(IAsyncResult result)
        {
            Console.WriteLine("Done");
        }
 
        static void App_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            Console.WriteLine("Got an error");
        }
    }
 
    class Worker
    {
        public void DoSomethingImpressive(int input)
        {
            throw new Exception("Ouch");
        }
    }
 
}

Well, I definitely need a solution to the problem, since exceptions definitely can happen off in my worker class. After some research, it turns out that you must call the EndInvode method on the delegate for the exception to bubble up. In my case, I wasn’t calling it because there was no return type. Now I understand why people frequently mention it is a best practice to always call EndInvoke, even if you don’t care about the return value (Doh!). The correct callback looks like this:

        static void Finished(IAsyncResult result)
        {
            AsyncResult ar = (AsyncResult)result;
            WorkerDelegate d = (WorkerDelegate)ar.AsyncDelegate;
 
            try
            {
                d.EndInvoke(ar);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Got an error on the callback");
            }
 
            Console.WriteLine("Done");
        }

I still haven’t discovered how/when the Application.ThreadException event handler gets called.

Posted on:
Posted in Winforms | Comments Off on Catching Thread Exceptions in C#

DataSets and Calculated Columns

Ran into a performance issue in a .Net remoting situation. A Winforms app is calling an application server asking for data. A relatively large DataSet (>10,000 rows, <6 columns) being passed over the wire was causing a performance problem. The database and application servers processed it quickly. Examining the transfer with WireShark showed that the transfer wasn’t so bad either. There was a flurry of data passed, and then a bunch of waiting on the client-side, with the client CPU usage around 50% the entire duration of the wait. Turns out there is a calculated column in one of the data tables. The column is not calculated on the application server-side, so as not to pass a bunch of data across the wire that would be unnecessary. The calc happens on the client. That was the source of the slowdown and CPU usage. In the end the solution to the problem was not using the calculated column, we found a different solution to fix the business problem. I suppose you could perform the calculation in the SQL statement that was ultimately filling the DataSet. That might take longer to transfer, but won’t slow down the client app.

Design with Users In Mind

We all spend lots of time delving into the technical aspects of our work, but don’t forget who we are creating all these wonderful apps for. You need to design your apps to work for the users, not create apps that the users need to work to use.

Required Reading: Four Modes of Seeking Information and How to Design for Them

WSOD – White Screen of Death in Winforms Designer

I’ve seen it many times in the past, now it has a name

Posted on:
Posted in Visual Studio, Winforms | Comments Off on WSOD – White Screen of Death in Winforms Designer

List Databinding Performance With DisplayMembers and ValueMembers

My copy of MSDN magazine arrived last night, and I read the article Practical Tips For Boosting The Performance Of Windows Forms Apps. Good read. Anyway, I was shocked to find out that I have been databinding lists improperly ever since I have been using .Net. I frequently wrote my code like this:

//Bad Code
combobox.DataSource = datatable;
combobox.DisplayMember = “State”;
combobox.ValueMember = “Id”;

//Good Code
combobox.DisplayMember = “State”;
combobox.ValueMember = “Id”;
combobox.DataSource = datatable;

Apparenly, order matters very much. In the first example, the combobox binds using the DisplayMember, then rebinds when updated with the ValueMember. In the second example, the binding only happens once.

In our current app, we have two lists that contain thousands of items that need to be bound, so we are binding them during the startup process so the user won’t wait when requesting that data. The startup time was reduced by just under 40% by changing the order of the code for binding.

Posted on:
Posted in .Net 2.0, Performance, Winforms | Comments Off on List Databinding Performance With DisplayMembers and ValueMembers

Comboboxes and Double-Clicks

The standard combobox control doesn’t support the double-click event, as it is actually a combination of more than one control itself. In my case, I am using the combobox in simple mode with a textbox at the top and a permanently open list directly below the textbox. I needed for the listbox below to respond to the user double-clicking a list item. I found a great solution in a Usenet post by Jacques Bourgeois in microsoft.public.dotnet.framework.windowsforms.controls. Essentially the code simulates a double-click using the single-click event and a timer control.

Declare a timer control in your class, and in the load event of the form instantiate the timer set the interval of the timer to the interval of the double-click as set in the user’s system:

this.comboDoubleClick = newTimer();

this.comboDoubleClick.Interval = SystemInformation.DoubleClickTime;

In the event handler for the timer, set the code to stop the timer:

this.comboDoubleClick.Enabled = false;

Add code to the single-click event handler to handle the double-click. When the event handler fires, if the timer is not enabled, start the timer (the first click). If the timer is enabled, a previous click has occurred within the system set interval for a double-click. This must be the second click of the double-click, so do whatever you needed the double-click to do and then disable the timer for the next single-click event.

private void Combo_MouseClick(object sender, MouseEventArgs e)
{
   
if (this.comboDoubleClick.Enabled == true)
    {
       
//Do double-click work here
       
this.comboDoubleClick.Enabled = false;
    }
   
else
   
{
       
this.comboDoubleClick.Start();
    }
}

Posted on:
Posted in .Net 2.0, Winforms | Comments Off on Comboboxes and Double-Clicks

Securing the Connection String with the Machine Key

d.code asks about securing connection strings. If you are willing to deal with a little unmanaged code, you can use the machine key or a user key via Data Protection API (DPAPI) functions instead of hiding your key somewhere. I first heard about the machine key at a Microsoft Security Summit that was touring around the country last spring. I based my work on this example, and a relevant MSDN article. The upside is that you do not need to maintain your own key somewhere, the downside is that any application run on the computer could decrypt your string, and that an encrypted string cannot be passed between computers (or users if you go that route), so you have to create the encrypted strings during deployment and have access to run an executeable on the production computer during deployment.

I created a small Winforms program that I run during deployment to encrypt my connection strings using the machine key. It just has two text boxes and two buttons for encrypting and decrypting strings. Once the deployment is done the exe is removed from the production machine. If someone compromised the box, they would have to know you used DPAPI (which they could only determine by spending the time to decompile your assembly) and have their own exe ready or create one to decrypt the strings. A little obfuscation on your code would contribute to the security in this situation.

Posted on:
Posted in ASP.NET, Security, Winforms | Comments Off on Securing the Connection String with the Machine Key