Posts Tagged Winform

Safely Update .Net Winform from Threads or Timer Ticks

Update The following article is one way to to achieve threading…But an easier way to try first is the BackGround Worker component (How to: Run an Operation in the Background). The below article shows how to invoke back to the form which is a step one does not have to do directly with the background worker due to its design.
Whenever one has threads or timers doing work on a winform application there is a need to update the screen from those operations. Most first time winform programmers fall into the trap where they try to update a screen control from those background processes and discover that their app locks up. The reason is that any data screen updating needs to be done by the GUI thread solely and not from any background task.
What the code should do is invoke a delegate back to the GUI thread to do the screen updating. This article shows one such way.
Step 1 define a delegate on the winform form class, and have an event derived from it which can be subscribed to such as:
// This is the format the delegate method
// will use when invoking back to the main gui
// thread.
public delegate void DataAcquired( object sender );
// The main thread will check for events
// invoked by subscribed threads here.
// This is the subscription point for the 
// threads.
public event DataAcquired OnDataAcquiredEvent;

In the above example we are just using an object to pass between the threads, but you can specify anything you want which is dictated by your circumstances.

Step 2 then have the form subscribe to the event (as in the constructor) which will be eventually be consumed by the worker threads or timers.

OnDataAcquiredEvent +=
    new DataAcquired(ThreadReportsDataAquiredEvent);

Note intellisense will do the above steps for you after the +=, accept them and it will do the next step

Step 3 Create the method that will handle the GUI update event

private void ThreadReportsDataAquiredEvent( object sender )
{
   tsslStatus.Text = sender.ToString();
}
  • Line 01: The thread/timer passes in an object which we will use to update the screen.
  • Line 03: We will take the object’s information from its ToString() and place it on a label on the form for the end user to see.

Step 4: In the timer tic method or the worker thread method we will call this method which will invoke back to the main thread:

private void PushStatus(string status)
{
    this.Invoke(this.OnDataAcquiredEvent,
                new object[] { status });
}

Note: One doesn’t have to create a separate method; the invoke line is all one has to do. We create the event and fire it to the GUI thread.

That is a safe way to update the screen for worker threads or timer tick events.

Share

Tags: , , , , ,

C# WinForms: Monitor Threads, Handles and Bytes on the Status Strip

This article demonstrates how to monitor performance of an application to report items as handles, memory or threads. It demonstrates how to create a status bar with the display of those performance items in real time using C# in .Net 2/3. One can see if the application is leaking any resources in those areas.

Why not have your application provide information to its running state such as handles, threads and the bytes being used. This article will show you how to create a Winform Application with a status bar where each label reports handles, threads and the bytes used.

Steps:

  1. Create a winform application.
  2. Add the Timer component to the form and set these properties:
    1. Timer: Change the Interval from 100 to 1000 so it ticks off every second.
    2. Timer: Set Enabled to True
    3. Create a event for the Tick event.
  3. Add three PerfomanceCounter Components to the form and name them pcPrivateBytes, pcHandles and pcThreadsBuild the application and run it. Then set the properties below:
    1. All: CategoryName = Process
    2. All: InstanceLifetime = Global
    3. All: MachineName = . (Yes a period)
    4. All: InstanceName = (Find the running application name in the drop down list, hence why we are running it.)
    5. pcHandles: CounterName = Handle Count
    6. pcThreads: CounterName = Thread Count
    7. pcPrivateBytes: CounterName = Private Bytes (Private bytes is only the bytes that the application allocates and not any extraneous bytes allocated by the system)
  4. Close the running application.
  5. Add a Status Strip to the application and create three status label areas named tsslHandles and tsslThreads, tsslPrivateBytes. Note the Private bytes is pretty dynamic, so placing it at the end is a good idea.
  6. In the timer tick event add this code which will get the current values of the performance moniter:
    tsslThread.Text  = string.Format("Threads: {0}", pcThreads.NextValue().ToString());
    tsslHandles.Text = string.Format("Handles: {0}", pcHandles.NextValue().ToString()); 
    
    // Divide the return of Private Bytes to something we will recognize.
    tsslPrivateBytes.Text = string.Format("Private Bytes: {0}", (pcPrivateBytes.NextValue() / 1000).ToString());
  7. Run the application and you should see this which gives you a running total of what your application is doing.

image

Share

Tags: , , ,

C# Winforms: Creating a Application which Minimizes to a Tray Icon

(Updated 02/14/2012 Code Examples use SyntaxHighlighter)

The goal is to having a working application which hides itself not to the taskbar but to an icon in the system tray. This is valid in .Net 2 and above. Here are the steps

  1. Create a Winform Application.
  2. Bring up the mainform.
  3. Drag a NotifyIcon component to the form.

NotifyIcon Setup

  1. In the properties set the icon to use. Note if you don’t have one grab the root.ico from the Visual Studio folder to use.
  2. We want to hide the icon initially so set the Visible property to false.
  3. Add this code to the click event
private void notifyIcon1_Click( object sender, EventArgs e )
{
    WindowState = FormWindowState.Normal;
}

Winform Setup

  1. Add this code to the resize event and you are done, it handles the states of the icon and taskbar button.
private void Form1_Resize( object sender, EventArgs e )
{
   if (WindowState == FormWindowState.Minimized)
   {
      ShowInTaskbar       = false;
      notifyIcon1.Visible = true;
   }
   else
   {
      ShowInTaskbar       = true;
      notifyIcon1.Visible = false;
   }
}

At this point compile and run. The application starts of as normal with a taskbar button but no icon. When the application is minimized it goes to the tray icon and there is no taskbar button. When the user clicks on the icon in the tray, it is returned to its previous state and the icon is removed.

Share

Tags: ,