4

次のコードは、私の問題を示す単純な例です。

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

namespace ConsoleApplication5
{
    class Program
    {
        static string LogFile = @"C:\test.log";

        static void Main(string[] args)
        {
            for (int i = 0;i<10;i++)
            {
                new Thread(new ParameterizedThreadStart(DoWork)).Start(i);
            }
            Console.ReadKey();
        }

        static void DoWork(object param)
        {
            int count = (int)param;

            try
            {
                using (FileStream fs = new FileStream(LogFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
                using (StreamWriter sw = new StreamWriter(fs))
                {
                    sw.WriteLine(DateTime.Now + " - Start " + count.ToString());
                    Thread.Sleep(2000); // simulate doing some work
                    sw.WriteLine(DateTime.Now + " - End " + count.ToString());
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(count.ToString() + ": " + e.Message);
                return;
            }
            Console.WriteLine(count.ToString() + ": Done.");
        }
    }
}

ここでの問題は、このメソッドを 10 回呼び出しても、通常は 1 つのエントリしかファイルに入らないことです。共有を許可するには、ファイルを開く必要があります。私が知る限り、例外はスローされません。どうしたの?

この例が隠している実際のコードでは、DoWork への各呼び出しは実際には個別のプロセスにありますが、テストでは結果は同じであることが示されています。ここで修正できる場合は、そこで修正できます。

4

2 に答える 2

5

ここで奇妙なことは何も起こっていません。「a.txt」というファイルがあり、それをメモ帳で 10 回開いたとします。その後、ファイルの内容を変更し、メモ帳のすべてのインスタンスに保存します。当然のことながら、最後に行った保存は、以前の 9 回の保存を書き換えるため、ファイルに永続化されるものです。

ここでも同じ振る舞いをしていると思います。各処理に Thread.Sleep があるため、すべてのファイルが同時に開かれます。そのため、保存する i ファイルは前回の保存 (i-1) を上書きします。

編集: Thread.Sleep(2000) を削除してみてください。ファイルにさらに多くのログが含まれます。

于 2008-11-17T18:05:48.197 に答える
1

SyncLock一度に 1 つのスレッドだけがファイルを開くようにするために使用します。その間、他のプロセスはクラッシュせず、queue.

于 2012-05-30T14:20:13.540 に答える