簡體   English   中英

多線程寫入WCF請求中的文本文件?

[英]Multithread Write into Text File in WCF request?

  1. 我有WCF方法,應該用一些數據創建文件。
  2. 該文件有時會被其他系統刪除。
  3. 我應該附加現有文件(如果存在)。
  4. 其他WCF請求不應丟失數據。

我考慮過不同的選擇,但看起來我應該在WCF中實現隊列。

我的想法和嘗試:

  1. 使用過TextWriter.Synchronized。 我發現Synchronized僅在為其創建實例的情況下起作用。
  2. 每個請求將創建自己的文件。 創建具有最大索引的文件的請求應將所有文件附加到一個文件中。 (當某些請求將使該文件已經是最后一個請求時將不起作用,將創建新請求)
  3. WCF中有一些隊列(如何實現?)

測試應用程序(模擬WCF方法WritePartToFile):

class Program
{
    private static string FileFormat = "file{0}.1001";
    static void Main(string[] args)
    {
        int countOfLines = 100;
        var processesCount = 200;

        var files = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.1001");
        foreach (var file in files)
        {
            File.Delete(file);
        }

        var expectedFilesCount = processesCount * countOfLines;
        Console.WriteLine("Trying to write. Processes:" + processesCount.ToString() + ". Lines:" + countOfLines + ". Expected lines:" + processesCount * countOfLines);
        var tasks = new List<Task>();
        for (int i = 1; i < processesCount; i++)
        {
            var result = Task.Factory.StartNew(() =>
            {
                WritePartToFile("Task:" + i.ToString(), countOfLines);
            });

            tasks.Add(result);
        }

        Console.WriteLine("Wait...");
        Task.WaitAll(tasks.ToArray());

        var fileName = string.Format(FileFormat, "");
        var lines = 0;
        if (File.Exists(fileName))
        {
            lines = File.ReadLines(fileName).Count();
        }

        if (lines != expectedFilesCount)
        {
            Console.WriteLine("Error!!! Total lines  (" + lines + ") != expected (" + expectedFilesCount + ")");
        }

        Console.WriteLine("Done. Lines added:" + lines + " Any key to exit.");
        Console.Read();
    }

    public static void WritePartToFile(string taskName, int countOfLines)
    {
        // Find free file name.
        var fileName = string.Format(FileFormat, "temp_1");

        int fileIndex = 1;
        while (File.Exists(fileName))
        {
            fileIndex++;
            fileName = string.Format(FileFormat, "temp_" + fileIndex);
        }

        var logFileStream = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.Read);
        using (var myWriter = new StreamWriter(logFileStream))
        {
            for (int i = 1; i < countOfLines; i++)
            {
                myWriter.WriteLine(taskName + ". Line number: " + i.ToString() + ". Guid:" + Guid.NewGuid().ToString());
            }
        }

        // Check is current file has MAX index (next index doesnot exists). Merge items (doesnot working)
        var nextFile = string.Format(FileFormat, "temp_" + fileIndex + 1);
        if (!File.Exists(nextFile))
        {
            var destinationFileName = string.Format(FileFormat, "");

            var mergedLines = new List<string>();
            // Merge all files into destination.
            var files = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.1001");
            foreach (var file in files)
            {
                if (File.Exists(file))
                {
                    mergedLines.AddRange(File.ReadAllLines(file));
                }
            }

            logFileStream = new FileStream(destinationFileName, FileMode.Append, FileAccess.Write, FileShare.None);
            using (var myWriter = new StreamWriter(logFileStream))
            {
                foreach (var item in mergedLines)
                {
                    myWriter.WriteLine(item);
                }
            }

        }

    }
}

PS我不能將此WCF方法設置為已同步,因為某些請求會將數據寫入其他文件,因此不需要同步。

您正在創建多個FileStream,每個任務一個,這似乎不正確。 即使它們是同步的,它們也不會在彼此之間同步,因為它們無法了解其他對象。

您需要做的是在主目錄中創建文件處理程序,然后將其傳遞給您的任務。 然后,每個任務將嘗試寫入相同的FileStream。 由於您要求該文件可以被系統的其他部分訪問,因此您不能一直保持打開狀態。

創建一個包含文件處理的新類。 此類將使用適當的鎖定來處理同步。 然后創建它的一個實例並將其傳遞給您的任務,這樣所有任務都將對該文件具有單個共享訪問權限。 在該類中,您可以添加邏輯以檢查其是否存在,打開文件並立即將其關閉

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM