Using Parallel and ThreadPool / QueueUserWorkItem in Combination with Writing / Locking Files

If you’ve wanted to combine parallel / multi-threading and also writing to files, you’ve probably experienced the issue of a file being locked when another process is writing at the same time. Something like:

An unhandled exception of type ‘System.IO.IOException’ occurred in mscorlib.dll

Additional information: The process cannot access the file ‘c:\yourfile’ because it is being used by another process.

One of the ways to get around this is utilize the “lock” statement.

In my below example, I’m running parallel tasks (including the optional MaxDegreeOfParallelism) and writing to a file. I also added a stopwatch and a .sleep to add time and debugging to the method. If you were to remove the lock() from the below, you should experience the ioexception.

Hope this helps as you create parallel tasks (so many great uses) and write files (maybe some simple logging, etc.)

You can also download the sample here.

using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace parallelTasks_Example
{
    //custom object for passing to queue task
    public class UpdateFile
    {
        public string lineData { get; set; }

        public string filePath { get; set; }

        public long timeTaken { get; set; }
    }

    internal class Program
    {
        //set an update to use a lock
        private static object fileLock = new object();

        private static void Main(string[] args)
        {
            //just for testing
            Stopwatch timer = new Stopwatch();

            timer.Reset();

            //get some data
            string[] contacts = { "jon", "jon2", "aaron", "efren", "diedrich", "tina", "sandy", "haylie", "trevor", "shondrella" };

            //do something with the data
            timer.Start();
            Parallel.ForEach(contacts, new ParallelOptions { MaxDegreeOfParallelism = 3 }, contact =>
                {
                    //do the task
                    Console.WriteLine(contact + " " + timer.ElapsedMilliseconds);
                    //create an object to past to the queue item
                    UpdateFile fileupdate = new UpdateFile { filePath = @"c:\temp\temp.txt", lineData = contact, timeTaken = timer.ElapsedMilliseconds };
                    //add the queue item
                    ThreadPool.QueueUserWorkItem(UpdateFile, fileupdate);
                });

            Console.ReadLine();
        }

        private static void UpdateFile(object fileData)
        {
            //set object to be locked
            lock (fileLock)
            {
                //get the file
                using (var fw = File.AppendText(((UpdateFile)fileData).filePath))
                {
                    //write the data
                    fw.WriteLine(((UpdateFile)fileData).lineData + ": " + ((UpdateFile)fileData).timeTaken.ToString());
                    //make process take long (for example)
                    System.Threading.Thread.Sleep(100);
                }
            }
        }
    }
}
Using Parallel and ThreadPool / QueueUserWorkItem in Combination with Writing / Locking Files

Error 500.19 with IIS / rewrite in web.config

500-19If you’ve added a rewrite to you web.config but are now receiving a HTTP Error 500.19 Internal Server Error, chances are you need to install the URL Rewrite Module. You might have assumed this is part of your install but it might be missing.

The install only takes a few seconds.

 

  1. Visit http://www.iis.net/downloads/microsoft/url-rewrite
  2. At the bottom of the page you can download the installer without using Web Platform.
  3. Run the MSI installer to add the URL Rewrite Module to your server. In my experience, I have not needed to reboot or reset IIS after installing this.
  4. Now you should successfully be able to use <rewrite>.

rewrite-mod

Error 500.19 with IIS / rewrite in web.config

c# Get Email Address from Active Directory (using Username) in Asp.net

dirSometimes it’s handy to grab either a username or email address (why not both?) from active directory. Below are the steps I believe you’ll need to get going quickly. In my example, I’m using VS2012 and .net 4.5.

1. Set your app to use windows authentication, you’ll need to set these to debug in VS:

Your web.config:

<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
    <authentication mode="Windows" />
    <identity impersonate="true" />

    <authorization>
      <allow users="*" />
    </authorization>
  </system.web>

  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
  </system.webServer>
</configuration>

Your project settings:

vs_winauth

2. Now in your application, add a reference to System.DirectoryServices:

dirservices

3. And in your code file:

using System.DirectoryServices;

4. A little function to search through active directory:

 private string uEmail(string uid)
        {
            DirectorySearcher dirSearcher = new DirectorySearcher();
            DirectoryEntry entry = new DirectoryEntry(dirSearcher.SearchRoot.Path);
            dirSearcher.Filter = "(&(objectClass=user)(objectcategory=person)(mail=" + uid + "*))";

            SearchResult srEmail = dirSearcher.FindOne();

            string propName = "mail";
            ResultPropertyValueCollection valColl = srEmail.Properties[propName];
            try
            {
                return valColl[0].ToString();
            }
            catch
            {
                return "";
            }

        }

5. And finally, how you can use:

string uName = "";
uName = uEmail(HttpContext.Current.User.Identity.Name.Replace(@"yourdomain\", ""));

Hope you enjoy! You can also use this method to retrieve other AD details (groups, full name, etc.).

c# Get Email Address from Active Directory (using Username) in Asp.net

c# Whole Word Matching (RegEx)

metal-detector-shmarkiiIf you’ve ever wanted to test a string to see if a word exists, but can’t use “.contains” because it doesn’t respect whole words (not that I would expect it to), below is a fast, simple way using Regex:

Of course you’ll need: using System.Text.RegularExpressions;

Now setup your pattern and Regex object:

string pattern = @"\bteam\b";
Regex rx = new Regex(pattern, RegexOptions.IgnoreCase);

Now create a match:

Match m = rx.Match("Teamwork is working together.");

Does the word exist:

if (m.Success) {
//no
}

Try again using a string with the whole word:

Match m = rx.Match("I am just part of the team.");

Does the word exist now?:

if (m.Success) {
//yes!
}

Of course, this is just a tiny portion of the power of Regex. Happy matching!

c# Whole Word Matching (RegEx)

.net SMTP – Sending An Email Message With A Display Name

email-blueIf you’ve ever used .net to send email messages (and I hope you have!) you may have wanted to send the message from or to not only an address, but also include a name. The ‘display name’ is the name that appears in many email clients instead of the address (think ‘Chris Bitting’ instead of ‘cbitting@something.com’). .Net honors the email standard of “Display Name <email@domain.com>”.

Below is a quick example on how this looks in vb.net:

Dim mail As New System.Net.Mail.MailMessage("""Some Body"" <person@company.com>", """A Different Person"" <person2@company2.com>", "Subject", "Body")

Below is a full example on an email function (include Imports System.Net.Mail): Continue reading “.net SMTP – Sending An Email Message With A Display Name”

.net SMTP – Sending An Email Message With A Display Name

IIS 8 ASP.Net Error “configuration section cannot be used…”

iis8logoWhen working with IIS 8 (or even 7 or 7.5), you may have run across this little gem / error: “This configuration section cannot be used at this path”

HTTP Error 500.19 – Internal Server Error
The requested page cannot be accessed because the related configuration data for the page is invalid.
Module / Handler IIS Web Core
Notification BeginRequest
Handler Not yet determined

You’ll want to open the applicationhost.config located in: C:\Windows\System32\inetsrv\config

And now find the lines like this:

<section name="handlers" overrideModeDefault="Deny" />
<section name="modules" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />

And change the Deny to Allow, like this:

<section name="handlers" overrideModeDefault="Allow" />
<section name="modules" allowDefinition="MachineToApplication" overrideModeDefault="Allow" />

Save the file, and you should be good!

IIS 8 ASP.Net Error “configuration section cannot be used…”

Update – More Details: Retrieving Email using Exchange Web Services Managed API 2.0 (c#)

email-orange-512x512So maybe you have started to use the Exchange Web Services Managed API to get email from inboxes and wanted to get a few additional details. Below are two of the most popular issues: Continue reading “Update – More Details: Retrieving Email using Exchange Web Services Managed API 2.0 (c#)”

Update – More Details: Retrieving Email using Exchange Web Services Managed API 2.0 (c#)

Retrieving and Sending Email using Exchange Web Services Managed API 2.0 (c#)

exlogoIf you haven’t already had the need, I’m sure you will at some point, to either retrieve email or send email through Exchange (not just relay or connect to Outlook) using .net. Since Microsoft introduced the Microsoft Exchange Web Services Managed API 2.0 this task has become much more efficient No more clunky 2.0 type web service references etc. Below is a complete chuck of code with a few samples. One sample function sends an email, the other retrieves email messages from an inbox with the option of filters.

Continue reading “Retrieving and Sending Email using Exchange Web Services Managed API 2.0 (c#)”

Retrieving and Sending Email using Exchange Web Services Managed API 2.0 (c#)

Downloading a remote file with vb.net / c# using WebClient

Can you believe it’s 2013 already? Me either. Anyhow, just wanted to provide a simple solution for a very popularly asked question: “how can I download a remote file?.” Well, below is a basic method using the WebClient class. It’s pretty cut and dry, just pass a remote file (ie: http://www.chrisbitting.com/image.jpg) and a local file (c:\temp\file.jpg) and it downloads. If you’re interested how to do this with cookies enabled for authentication, let me know!

vb.net

Private Sub dloadhttpFile(fileToDownload As String, localFile As String)
        'Examples:
        'fileToDownload = http://www.chrisbitting.com/image.jpg
        'localFile = c:\files\someimage.jpg

        Try
            'create an instance of WebClient - the heart of downloading a file
            Dim fileReader As New WebClient()

            'check if the file already exists locally
            If Not (System.IO.File.Exists(localFile)) Then
                fileReader.DownloadFile(fileToDownload, localFile)
            End If
        Catch ex As HttpListenerException
            Console.WriteLine(("Error Downloading: " & fileToDownload & " - ") + ex.Message)
        Catch ex As Exception
            Console.WriteLine(("Error Downloading: " & fileToDownload & " - ") + ex.Message)
        End Try
    End Sub

c#

   private void dloadhttpFile(string fileToDownload, string localFile)
        {
             //Examples:
             //fileToDownload = http://www.chrisbitting.com/image.jpg
             //localFile = c:\files\someimage.jpg

            try
            {
                //create an instance of WebClient - the heart of downloading a file
                WebClient fileReader = new WebClient();

                //check if the file already exists locally
                if (!(System.IO.File.Exists(localFile)))
                {
                    fileReader.DownloadFile(fileToDownload, localFile);
                }
            }
            catch (HttpListenerException ex)
            {
                Console.WriteLine("Error Downloading: " + fileToDownload + " - " + ex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error Downloading: " + fileToDownload + " - " + ex.Message);
            }
        }
Downloading a remote file with vb.net / c# using WebClient