Solved

file accessing problem in multi threading

Posted on 2007-12-05
17
337 Views
Last Modified: 2013-11-07
hi,

i have a asp.net application , when application starts a dedicated thread is started to check if a file is there. if not create it.

2. my aspx page do the appending on that file.
my process is quad core. when i start the application both the thread try to create and append simultanously. so file is used by another process problem is there.

can any
--------------------- in global .aspx-------------------------------

protected void Application_Start(Object sender, EventArgs e)

		{

            try

            {

                ThreadStart job = new ThreadStart(FileNameGenerator.CreateMove);

                Thread thread = new Thread(job);

                thread.Name = "Moniter_Log";

                thread.Start();

            }

            catch (Exception ex)

            {

            

                        }
 

		}

--------------

method being called in abovet thread-----------------

 public static void CreateMove()

{

     string FileName = path+DateTime.Now.ToString("dd_MM_yyyy_HH")+".txt";
 

     while (true)

     {

         try

         {
 

             String[] files = Directory.GetFiles(path);

             if (!File.Exists(FileName) && files.Length > 0)

             {

                 string oldPath = ConfigurationManager.AppSettings["FilePath2"];

                 foreach (string file in files)

                     File.Move(file, file.Replace(path, oldPath));
 

                 FileStream stream = new FileStream(FileName, FileMode.Append, FileAccess.ReadWrite,FileShare.Write);

                // File.Create(FileName);
 

             }

             else if (!File.Exists(FileName))

             {

                 FileStream stream = new FileStream(FileName, FileMode.Append, FileAccess.ReadWrite, FileShare.Write);
 

             }

         }
 
 

         catch (Exception ex)

         {

         }

         finally

         {

             Thread.Sleep(1000 * 60 * 1);

         }

     }

 }

-------------------------------------------------------------------

in aspx page

 protected void Page_Load(object sender, EventArgs e){

public void Write(string Text,string FileName)

        {

            while (!File.Exists(FileName))

                Thread.Sleep(200);

           lock(this)

           {
 

               FileStream stream = new FileStream(FileName, FileMode.Append, FileAccess.ReadWrite);

               StreamWriter writer = new StreamWriter(stream);

           //StreamWriter objStreamWriter1 = File.AppendText(FileName);

           writer.WriteLine(Text);

           writer.Close();

       }

       }}
 

-------------------------------------------------------------

Open in new window

0
Comment
Question by:sitg
  • 13
  • 3
17 Comments
 
LVL 40

Expert Comment

by:evilrix
Comment Utility
0
 
LVL 40

Expert Comment

by:evilrix
Comment Utility
0
 
LVL 40

Expert Comment

by:evilrix
Comment Utility
0
 
LVL 40

Assisted Solution

by:evilrix
evilrix earned 500 total points
Comment Utility
Basically, you need to ensure that access to the file is mutually exclusive in both threads so that it can only be used by one thread at a time. You normally do this using a thread synchronization primitive such as a Mutex. The mutex object has ownership semantics. It's like having a group of people and only the one holding the red flag can speak. So, a thread will try to take ownership of the mutex and if it can it is allowed to access the resource, else it waits (blocks) on the mutex until whoever does own it gives up ownership. The links I've posted above and below should provide you all the info you need to do this.

http://msdn.microsoft.com/msdnmag/issues/03/01/NET/
http://msdn.microsoft.com/msdnmag/issues/04/09/BasicInstincts/

There's a lot to read but multi-threaded programming can be tricky -- there are no short-cuts. You are better off taking the time to read and understand these articles so as to ensure you fully understand what you are doing here. For this reason I have not attempted to provide code to fix this for you. If I did and it went wrong you'd have no idea how to fix it (or how to diagnose it) and as such you are better off understanding and fixing for yourself :)
0
 

Author Comment

by:sitg
Comment Utility
hi evilrix:

it will be nice of you ,  if you give a fix of this code .
because i have very less time right now.

i will read on getting the time.

Thanx
0
 
LVL 40

Accepted Solution

by:
evilrix earned 500 total points
Comment Utility
Ok, this is untested (I have no way of testing it) but it's something like this...
// CREATE MUTEX

// Needs to live somewhere ALL threads can see it

static Mutex mtx = new Mutex();
 

--------------------- in global .aspx-------------------------------

protected void Application_Start(Object sender, EventArgs e)

		{

            try

            {

                ThreadStart job = new ThreadStart(FileNameGenerator.CreateMove);

                Thread thread = new Thread(job);

                thread.Name = "Moniter_Log";

                thread.Start();

            }

            catch (Exception ex)

            {

            

                        }

 

		}

--------------method being called in abovet thread-----------------

 public static void CreateMove()

{

     string FileName = path+DateTime.Now.ToString("dd_MM_yyyy_HH")+".txt";

 

     while (true)

     {

         try

         {

             mtx.WaitOne(); // LOCK MUTEX

 

             String[] files = Directory.GetFiles(path);

             if (!File.Exists(FileName) && files.Length > 0)

             {

                 string oldPath = ConfigurationManager.AppSettings["FilePath2"];

                 foreach (string file in files)

                     File.Move(file, file.Replace(path, oldPath));

 

                 FileStream stream = new FileStream(FileName, FileMode.Append, FileAccess.ReadWrite,FileShare.Write);

                // File.Create(FileName);

 

             }

             else if (!File.Exists(FileName))

             {

                 FileStream stream = new FileStream(FileName, FileMode.Append, FileAccess.ReadWrite, FileShare.Write);

 

             }
 

             mtx.ReleaseMutex(); // UNLOCK MUTEX

         }

 

 

         catch (Exception ex)

         {

         }

         finally

         {

             Thread.Sleep(1000 * 60 * 1);

         }

     }

 }

-------------------------------------------------------------------

in aspx page

 protected void Page_Load(object sender, EventArgs e){

public void Write(string Text,string FileName)

        {

            while (!File.Exists(FileName))

                Thread.Sleep(200);

           lock(this)

           {

              mtx.WaitOne(); // LOCK MUTEX

 

           FileStream stream = new FileStream(FileName, FileMode.Append, FileAccess.ReadWrite);

               StreamWriter writer = new StreamWriter(stream);

           //StreamWriter objStreamWriter1 = File.AppendText(FileName);

           writer.WriteLine(Text);

           writer.Close();
 

           mtx.ReleaseMutex(); // UNLOCK MUTEX

       }

       }}

 

-------------------------------------------------------------

Open in new window

0
 
LVL 40

Assisted Solution

by:evilrix
evilrix earned 500 total points
Comment Utility
^^^Look for the Mutex I've added, called mtx, which needs to be visible to all threads and locked (WaitOne) before file access and unlocked (ReleaseMutex) after you finish accessing the file in ALL threads.
0
 
LVL 40

Expert Comment

by:evilrix
Comment Utility
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 40

Expert Comment

by:evilrix
Comment Utility
The code below is a working example of how a mutex synchronizes threads. Without it the output is a mess. With it each thread outputs 10 lines and then defers to the other. To see the difference comment out the bits I've noted in the code
using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Text.RegularExpressions;

using System.Threading;
 
 

namespace cs_console

{

    class Program

    {

        static bool bQuit = false;

        static Mutex mtx = new Mutex(false);
 

        static void ThreadFunc()

        {

            while (!bQuit)

            {

                for (int x = 0; x < 10; ++x)

                {

                    //////////////////////////////////////////////////

                    // Comment out to see what it's like with no mutex

                    mtx.WaitOne();

                    //////////////////////////////////////////////////

                    for (int y = 0; y < 10; ++y)

                    {

                        Console.WriteLine("In thread: " + y.ToString());

                        Thread.Sleep(0);

                    }

                    //////////////////////////////////////////////////

                    // Comment out to see what it's like with no mutex

                    mtx.ReleaseMutex();

                    //////////////////////////////////////////////////

                }

            }

        }

        static void Main(string[] args)

        {

            Thread thread = new Thread(new ThreadStart(Program.ThreadFunc));

            thread.Start();
 

            for (int x = 0; x < 10; ++x)

            {

                //////////////////////////////////////////////////

                // Comment out to see what it's like with no mutex

                mtx.WaitOne();

                //////////////////////////////////////////////////

                for (int y = 0; y < 10; ++y)

                {

                    Console.WriteLine("In main: " + y.ToString());

                    Thread.Sleep(0);

                }

                //////////////////////////////////////////////////

                // Comment out to see what it's like with no mutex

                mtx.ReleaseMutex();

                //////////////////////////////////////////////////

            }
 

            bQuit = true;
 

            thread.Join();

        }

    }

}

Open in new window

0
 

Author Comment

by:sitg
Comment Utility
thanks,
but i have question.
if the both threads runs simultaneosly on two processors.

because if at same time both request for
  mtx.WaitOne();

will it work ...
0
 
LVL 40

Expert Comment

by:evilrix
Comment Utility
Yes, only one will win and the other will block. This object is designed to be used in this way.
0
 
LVL 40

Assisted Solution

by:evilrix
evilrix earned 500 total points
Comment Utility
Of course, you won't know which will win -- that'll be non-deterministic.
0
 
LVL 40

Expert Comment

by:evilrix
Comment Utility
If you need to synchronize this is some way you can either create the mutex so the thread creating it has initial ownership or you can use an AutoResetEvent to synchronize this ion some way.

http://msdn2.microsoft.com/en-us/library/system.threading.autoresetevent.aspx
0
 
LVL 40

Expert Comment

by:evilrix
Comment Utility
The following example uses 2 auto reset events to pass signals between main and thread. Comments in the code should clarify what is going on: -
using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Text.RegularExpressions;

using System.Threading;
 
 

namespace cs_console

{

    class Program

    {

        static bool bQuit = false;

        static Mutex mtx = new Mutex(false);

        static AutoResetEvent autoEventThread = new AutoResetEvent(false);

        static AutoResetEvent autoEventMain = new AutoResetEvent(false);
 

        static void ThreadFunc()

        {

            while (!bQuit)

            {

                for (int x = 0; x < 10; ++x)

                {

                    //////////////////////////////////////////////////////

                    // Wait for main to signal

                    autoEventThread.WaitOne();

                    //////////////////////////////////////////////////////
 

                    if (!bQuit)

                    {

                        //////////////////////////////////////////////////

                        // Comment out to see what it's like with no mutex

                        mtx.WaitOne();

                        //////////////////////////////////////////////////

                        for (int y = 0; y < 10; ++y)

                        {

                            Console.WriteLine("In thread: " + y.ToString());

                            Thread.Sleep(0);

                        }

                        //////////////////////////////////////////////////

                        // Comment out to see what it's like with no mutex

                        mtx.ReleaseMutex();

                        //////////////////////////////////////////////////

                        // Signal main

                        autoEventMain.Set();

                        //////////////////////////////////////////////////

                    }

                }

            }

        }

        static void Main(string[] args)

        {

            Thread thread = new Thread(new ThreadStart(Program.ThreadFunc));

            thread.Start();
 

            for (int x = 0; x < 10; ++x)

            {

                //////////////////////////////////////////////////

                // Use event to ensure main runs before thread

                // and do two main loops to one thread loop

                if ((x > 0) && (x % 2) == 0)

                {

                    // Signal thread

                    autoEventThread.Set();

                    // Wait for thread to signal

                    autoEventMain.WaitOne();

                }

                //////////////////////////////////////////////////

                // Comment out to see what it's like with no mutex

                mtx.WaitOne();

                //////////////////////////////////////////////////

                for (int y = 0; y < 10; ++y)

                {

                    Console.WriteLine("In main: " + y.ToString());

                    Thread.Sleep(0);

                }

                //////////////////////////////////////////////////

                // Comment out to see what it's like with no mutex

                mtx.ReleaseMutex();

                //////////////////////////////////////////////////

            }
 

            bQuit = true;
 

            //////////////////////////////////////////////////////

            // Signal thread

            autoEventThread.Set();

            //////////////////////////////////////////////////////
 

            thread.Join();

        }

    }

}

Open in new window

0
 
LVL 40

Assisted Solution

by:evilrix
evilrix earned 500 total points
Comment Utility
Ensure your code is exception safe by using a try/finally block to ensure the mutex is always freed, even if there is an exception throw: -
using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Text.RegularExpressions;

using System.Threading;

 

 

namespace cs_console

{

    class Program

    {

        static bool bQuit = false;

        static Mutex mtx = new Mutex(false);

 

        static void ThreadFunc()

        {

            while (!bQuit)

            {

                for (int x = 0; x < 10; ++x)

                {

                    if (!bQuit)

                    {

                        try

                        {

                            //////////////////////////////////////////////////

                            // Comment out to see what it's like with no mutex

                            mtx.WaitOne();

                            //////////////////////////////////////////////////

                            for (int y = 0; y < 10; ++y)

                            {

                                Console.WriteLine("In thread: " + y.ToString());

                                Thread.Sleep(0);

                            }

                            //////////////////////////////////////////////////

                        }

                        finally

                        {

                            //////////////////////////////////////////////////

                            // Comment out to see what it's like with no mutex

                            mtx.ReleaseMutex();

                            //////////////////////////////////////////////////

                        }

                    }

                }

            }

        }

        static void Main(string[] args)

        {

            Thread thread = new Thread(new ThreadStart(Program.ThreadFunc));

            thread.Start();

 

            for (int x = 0; x < 10; ++x)

            {

                try

                {

                    //////////////////////////////////////////////////

                    // Comment out to see what it's like with no mutex

                    mtx.WaitOne();

                    //////////////////////////////////////////////////

                    for (int y = 0; y < 10; ++y)

                    {

                        Console.WriteLine("In main: " + y.ToString());

                        Thread.Sleep(0);

                    }

                    //////////////////////////////////////////////////

                }

                finally

                {

                    //////////////////////////////////////////////////

                    // Comment out to see what it's like with no mutex

                    mtx.ReleaseMutex();

                    //////////////////////////////////////////////////

                }

            }

 

            bQuit = true;

 

            thread.Join();

        }

    }

} 

Open in new window

0
 
LVL 1

Expert Comment

by:uggel
Comment Utility
Hello sitg,

about the two processor question.

The definition of a thread is that it is a "subprocess" within a process that share memory with the other subprocesses. That way the address to the semaphore/mutex is the same in all threads within that process. Your quad cores also share cache physically which makes things fast and easy. Compare this to actually having 4 SIMD-coupled procs on a quad proc mother board.
0
 

Author Comment

by:sitg
Comment Utility
evilrix:

it is not working i just  put the mutex object in the global.asax. which is visible to all.
and rest of the code as you given
put same file access problem is occuring. or safe handle has been closed problem
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Exception in Log4Net 1 18
Expando 4 33
Data Saving 5 24
Create a form which is copy of a form in vb.net 2 17
This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now