Devign Blog

News and Interest

Locking shared objects in .NET

clock October 16, 2008 23:56 by author devignadmin

If you have a shared (static) object in a class, and multiple threads handle this object, potentially at the same time, you might run into some problems. For example, let's say you have a shared collection of items. Now you might have a method to add an item, a method to remove an item, and a method to retrieve an item. But what happens when one thread removes the item that another thread is busy retrieving? You might get an "Index out of range" exception. But how can one prevent this? By using locks. In VB.NET, we have SyncLock. This is mainly used to prevent two threads or instances of a class running the same piece of code at the same time. But it can also be used to lock specific objects, so that only one thread or instance changes that object at a time. Let's look at an example.

Let's declare our shared object, and a special object, used to lock the critical parts.

   1: Private Shared ItemList As New ArrayList
   2: Private Shared LockObject As New Object

Next, let's setup some methods to handle this object.

   1: Public Sub AddItem(ByVal obj As Object)
   2:     SyncLock LockObject
   3:         ItemList.Add(obj)
   4:     End SyncLock
   5: End Sub
   6:  
   7: Public Function GetItem(ByVal i As Integer) As Object
   8:     SyncLock LockObject
   9:         If (i >= 0) And (i < ItemList.Count) Then
  10:             Return ItemList(i)
  11:         End If
  12:     End SyncLock
  13: End Function

The code will look similar to remove an item from the list.

The trick is to make the locking object shared as well. This means that when a thread wants to do anything to our shared object, it has to wait until LockObject is not locked by any other thread. That should prevent any conflicts.

If you have any suggestions about improving the code, or have an interesting thought, please leave a comment below.



Dealing with file access problems in C#

clock October 16, 2008 12:06 by author devignadmin

At some point in a production environment you will come across the problem of handling a file that is locked by another process on the machine. This presents the challenge of what to do in such a case. If this does occur, .NET will throw an exception. Can we check whether a file is locked before we access it? It might be possible, but in reality it doesn't help us. Because in the time between the check and the actual file access, another process has plenty of opportunity to lock the file again, and then we are back to square one.

So, what can we do?

One way to handle this scenario is to retry our file operation until the file is not locked anymore. Of course we need to give it a maximum number of retries, otherwise we might get stuck in an endless loop (i.e. another process might have a permanent lock on the file). And if the file stays locked during our attempts, we then gracefully handle the exception. It's not the perfect solution, but it makes it more likely that our code will complete successfully.

Now, how do we accomplish this in C#? The following method could be used to copy a file with a specified number of retries.

   1: using System.IO;
   2: using System.Threading;
   3:  
   4: private bool CopyFile(string fromPath, string toPath, string newFileName, int numRetries)
   5: {
   6:     int i;
   7:     FileInfo fromFile;
   8:     DirectoryInfo destPath;
   9:     try
  10:     {
  11:         fromFile = new FileInfo(fromPath);
  12:         destPath = new DirectoryInfo(toPath);
  13:         i = 0;
  14:         while (true)
  15:         {
  16:             try
  17:             {
  18:                 i++;
  19:                 fromFile.CopyTo(Path.Combine(destPath.FullName, newFileName), true);
  20:                 return true; // Copy was successful
  21:             }
  22:             catch (IOException ioEx)
  23:             {
  24:                 if (i >= numRetries)
  25:                 {
  26:                     exit; // exit loop - maximum retries reached
  27:                 }
  28:                 else
  29:                 {
  30:                     Thread.Sleep(250); // Wait briefly before trying again
  31:                 }
  32:             }
  33:         }
  34:     }
  35:     catch (Exception ex)
  36:     {
  37:         // Handle exception
  38:         return false;
  39:     }
  40:     return false; // Copy was not completed
  41: }

 

There we go. This method is only effective with files that are locked temporarily, though. If a file is locked for longer periods, we need to handle it differently. Waiting for the file to be released is mostly not realistic, so we might want to just handle the exception and get on with things.

If you have any questions or suggestions on how to improve this code, please feel free to leave a comment below.



Controlling Windows Services in C#

clock October 7, 2008 15:12 by author devignadmin

With the .NET framework it is quite easily possible to control Windows Services programmatically. In this article I will briefly demonstrate how this can be done. To get to most methods relating to Windows Services, you need access to the System.ServiceProcess namespace. The method call to perform operations are then relatively simple.

Installing a Windows Service

First of all, let's take a look at installing a Windows Service programmatically. I use the following function to install a service, specifying the Service's .exe file as a parameter. The code look as follows:

   1: using System.ServiceProcess;
   2:  
   3: private bool InstallService(string FilePath)
   4: {
   5:     try
   6:     {
   7:         // Install Service
   8:         ManagedInstallerClass.InstallHelper(new string[] { FilePath });
   9:  
  10:         // Set Logon User
  11:         string objPath = string.Format("Win32_Service.Name='{0}'", "ServiceName");
  12:         using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
  13:         {
  14:             object[] wmiParams = new object[11];
  15:             // User Name
  16:             wmiParams[6] = "LocalSystem";
  17:             // Password
  18:             wmiParams[7] = "";
  19:             service.InvokeMethod("Change", wmiParams);
  20:         }
  21:  
  22:         return true;
  23:     }
  24:     catch (Exception ex)
  25:     {
  26:         return false;
  27:     }
  28: }

The installation consists of only one line of code (line 8), but after that I set the logon user for the Service. In my case the service had to log on using the Local System account. If you do not need to change this, that part of the code is not necessary.

Starting and stopping Windows Service

Next, we look at starting and stopping our service. The following code performs those functions:

   1: private bool StartService(string serviceName)
   2: {
   3:     // Get list of available services
   4:     ServiceController[] services = ServiceController.GetServices();
   5:     // Loop through services
   6:     for (int i = 0; i < services.Length; i++)
   7:     {
   8:         // Check if service is the one we need
   9:         if (services[i].ServiceName == serviceName)
  10:         {
  11:             // Get a controller object for this service
  12:             ServiceController sc = new ServiceController(services[i].DisplayName, Environment.MachineName);
  13:             // If the service is not running yet, start it
  14:             if (sc.Status != ServiceControllerStatus.Running)
  15:                 sc.Start();
  16:         }
  17:     }
  18: }
  19:  
  20: private bool StopService(string serviceName)
  21: {
  22:     // Get list of available services
  23:     ServiceController[] services = ServiceController.GetServices();
  24:     // Loop through services
  25:     for (int i = 0; i < services.Length; i++)
  26:     {
  27:         // Check if service is the one we need
  28:         if (services[i].ServiceName == serviceName)
  29:         {
  30:             // Get a controller object for this service
  31:             ServiceController sc = new ServiceController(services[i].DisplayName, Environment.MachineName);
  32:             // If the service is not stopped, stop it now
  33:             if (sc.Status != ServiceControllerStatus.Stopped)
  34:                 sc.Stop();
  35:         }
  36:     }
  37: }

And those are the basics of controlling Windows Services. There are some more methods available, like pausing and resuming a service, but you can easily adapt the code above to get those functions.

If you have any problems or questions about this code, leave a comment, and I'll try to help out.



Converting videos to SVI format for the Samsung YP-S3

clock October 2, 2008 00:08 by author devignadmin

Samsung_YP_S3_azul I recently bought the Samsung YP-S3 MP3 player. It's a great little gadget, but I ran into some problems converting videos (AVI & MPG) into a format that can be played on the device. The bundled software that Samsung provided wasn't able to do the conversion properly, even though it claimed to. The Internet didn't immediately yield the solutions I was hoping for either. From what I read, the SVI format Samsung uses is just MP4, with some restrictions. But any configurations I tried had no effect, and all I got was a message saying that the videos were not in the correct format.

avc Finally I discovered a forum post where someone suggested a tool called Any Video Converter. There is a "lite" version that is free, and so I downloaded it and tried it. I converted my AVIs to MP4, and then ran them through the Samsung software. Voila! It worked. You can even customize individual settings, like resolution, FPS, sound quality, etc. And I suspect this method can be used for some of Samsung's other players as well.

Free Download: Any Video Converter

Input formats: AVI, MPG, MOV, FLV, and loads of others

Output formats: MPG, AVI, MP4, FLV, WMV



SMTP testing without sending out mail

clock October 2, 2008 00:05 by author devignadmin

devnull A few weeks ago I was working on a rather large system that was still quite the black box to me. I was trying to get it to run when I suddenly realized it had been sending out error reports for about 20 or 30 minutes, at a rate of a few per second. One of my co-workers received over a 1000 of these e-mails. That brought up the issue of how I would test without having the system send out all those mails. And just turning off the local SMTP server wasn't an option either. So I set about finding an alternative that would allow me to continue testing without having to worry about mails being sent out blindly. I found some solutions that required me to integrate assemblies into my .NET solution, but this was not practical at the time. Finally I found something that suited my requirements. The little program that came to the rescue is called DevNull. It runs independently of your system, and "catches" any mails that are sent via SMTP. It has the option of saving the e-mails on your hard drive so you can view them later. And that was perfect for what I needed. So if you need to test an application that send out e-mails without the mails actually going out, then DevNull is perfect for you.

Free Download: DevNull

Operating System: Independent

Size: 458 KB



Search


Bookmark and Share

 Subscribe to this feed

Calendar

<<  January 2009  >>
SuMoTuWeThFrSa
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

Archive

Tags

Categories


Blogroll

    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2009

    Sign in