C # Multithreading read and write the same file processing

Source: Internet
Author: User
Tags finally block

When multithreaded access reads and writes the same file, an exception is frequently encountered: "The file is in use by another process, so the process cannot access this file ."

Multi-threaded access to Uniform resource exceptions,

Solution 1, ensure that the read-write operation is single-threaded, you can use lock

Solution 2, use System.Threading.ReaderWriterLockSlim, lock processing for read and write operations

Read-write locks are managed with ReaderWriterLockSlim objects as lock management resources, and locking of the same file in different ReaderWriterLockSlim objects is also treated as a different lock. This discrepancy may again cause concurrent write problems for the file, so ReaderWriterLockSlim should be defined as a read-only static object.

ReaderWriterLockSlim has several key methods, this article discusses only write locks:

The call to the Enterwritelock method enters the write state, is blocked until the calling thread enters the lock state, and therefore may never be returned .
Call the Tryenterwritelock method to enter the write state, which specifies the time interval for blocking, and returns False if the calling thread does not enter write mode during this interval.
Call the Exitwritelock method to exit the write state, and the finally block should be used to execute the Exitwritelock method, ensuring that the caller exits write mode.

One, not with the lock processing, multi-threaded access to file a variable when thrown exception

Static voidMain (string[] args) {    //The iteration runs the write log record, because multiple threads writing to the same file at the same time will cause an errorParallel.For (0, Logcount, E ={writelog ();    }); Console.read ();}Static intLogcount = -;Static intFailedcount =0;Static intWritecount =0;Static voidWritelog () {Try{Writecount++; Loghelper.loghelper _log=NewLoghelper.loghelper ("G:\\temp2\\one.txt",true); DateTime Now=DateTime.Now; varLogcontent =string. Format ("Tid: {0}{1} {2}=>{3}\r\n", Thread.CurrentThread.ManagedThreadId.ToString (). PadRight (4), now. Tolongdatestring (), now.        Tolongtimestring (), writecount); _log.    WriteLine (logcontent); }    Catch(Exception ex) {Failedcount++; Console.WriteLine ("cumulative number of errors:"+failedcount); Console.WriteLine (ex.    Message); }}

Second, using read-write lock synchronous write file processing

//read-write lock, when the resource is in write mode, other thread writes need to wait until the end of the write to continue writingstatic ReaderWriterLockSlim Logwritelock = new ReaderWriterLockSlim ();Static voidWritelog () {Try    {        //Set read/write locks to write mode exclusive resources, other write requests need to wait until the end of this write to continue writing//Note: Holding a reader lock or writer lock for a long time can cause other threads to starve (starve).        For best performance, you need to consider re-structuring your application to minimize write access duration. //from a performance point of view, the request enters write mode should immediately precede the file operation, where the write mode is entered only to reduce the complexity of the code//because the Enter and exit write mode should be within the same try-finally statement block, the exception cannot be triggered until the request enters write mode, or the number of releases greater than the number of requests will trigger an exception Logwritelock.enterwritelock (); Writecount++; Loghelper.loghelper _log=NewLoghelper.loghelper ("G:\\temp2\\one.txt",true); DateTime Now=DateTime.Now; varLogcontent =string. Format ("Tid: {0}{1} {2}=>{3}\r\n", Thread.CurrentThread.ManagedThreadId.ToString (). PadRight (4), now. Tolongdatestring (), now.        Tolongtimestring (), writecount); _log.    WriteLine (logcontent); }    Catch(Exception ex) {Failedcount++; Console.WriteLine ("cumulative number of errors:"+failedcount); Console.WriteLine (ex.    Message); }    finally    {        //exit write mode to release resource consumption//Note: One request corresponds to one release//An exception is triggered if the number of releases is greater than the number of requests [write lock is released without being persisted]//an exception will be triggered if the request processing is complete and not released [this mode does not allow the write lock to be retrieved recursively] Logwritelock.exitwritelock (); }}

Third, add: When initializing FileStream, using a constructor that contains file share properties (System.IO.FileShare) is more secure and efficient than using a custom thread lock

 1     class Program2     { 3         Static intLogcount = -; 4         Static intWritedcount =0; 5         Static intFailedcount =0; 6  7         Static voidMain (string[] args)8         { 9             //To run an iteration to write a log recordTenParallel.For (0, Logcount, E = One             { AWritelog (); -             }); -  theConsole.WriteLine (string. Format ("\r\nlog count:{0}.\t\twrited count:{1}.\tfailed count:{2}.", Logcount.tostring (), writedcount.tostring (), failedcount.tostring ( )); -Console.read (); -         } -  +         Static voidWritelog () -         { +             Try A             { at                 varLogFilePath ="Log.txt"; -                 varnow =DateTime.Now; -                 varLogcontent =string. Format ("Tid: {0}{1} {2}. {3}\r\n", Thread.CurrentThread.ManagedThreadId.ToString (). PadRight (4), now. Tolongdatestring (), now. Tolongtimestring (), now.Millisecond.ToString ()); -  -                 varLogcontentbytes =Encoding.Default.GetBytes (logcontent); -                 // because the file sharing mode is set to allow subsequent writes , even if multiple threads write to the file at the same time, they will wait until the previous thread has finished writing and then execute without error in                 using(FileStream logFile =NewFileStream (LogFilePath, FileMode.OpenOrCreate, FileAccess.Write, fileshare.write)) -                 { toLogfile.seek (0, seekorigin.end); +Logfile.write (Logcontentbytes,0, logcontentbytes.length); -                 } the  *writedcount++; $             }Panax Notoginseng             Catch(Exception ex) -             { thefailedcount++; +Console.WriteLine (ex. Message); A             } the         } +}

More:

C # Get the current path method collation

C # gets current system disk characters, system directories, desktops, etc.

C # Get a list of disks and information

C # Multithreading read and write the same file processing

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.