2

タスクを使用して複数のファイルをsftpサーバーにアップロードしています。しかし、現在起こっていることは、複数のタスクが並行して実行されるときに同じ「fileName」が生成されているということです。毎回個別のファイル名が生成されるようにしたい。

//Simplified version of my code:
processingTasks = 1000;
while (processingTasks > 0)
{
    processingTasks --;
    Task<string> task = Task<string>.Factory.StartNew(() =>
    {
          string fileName = DateTime.Now.ToString("yyyyMMddHHmmss") + ".txt";
          return UploadFileToSFTP(fileName, fileContent);
    });
}

次のことは私にとってうまくいき、明確な日時のファイル名を私に与えますか、それともこれを行うためのより良い方法がありますか?

processingTasks = 1000;
while (processingTasks > 0)
{
     processingTasks --;
     Task<string> task = Task<string>.Factory.StartNew(() =>
     {
           lock(file) //Will only one task go inside this at a time?
           {
               Thread.Sleep(1000);
               string fileName = DateTime.Now.ToString("yyyyMMddHHmmss") + ".txt";
           }

           return UploadFileToSFTP(fileName, fileContent);
     });
}
4

3 に答える 3

2

Emileのアイデアを使用して、「一意のタイムスタンプ」を生成できます。DateTime.Nowこの時間がまだ返されていない場合は戻り、それ以外の場合は、将来の最初の空き秒を返します。

このようにすると、タイムスタンプが少しだけ(または、このメソッドを1秒に1回以上長時間呼び出すと、大きくなると)不正確になりますが、待つ必要がないことを意味します。私には壊れやすい。

コード内:

public static class UniqueTimestamp
{
    private static readonly object Lock = new object();
    private static DateTime LastTimestamp = DateTime.MinValue;

    private static DateTime RoundToSecond(DateTime dt)
    {
        return new DateTime(dt.Year, dt.Month, dt.Day,
                            dt.Hour, dt.Minute, dt.Second);
    }

    public static DateTime GetTimestamp()
    {
        var now = RoundToSecond(DateTime.Now);
        DateTime timestamp;
        lock (Lock)
        {
            if (now > LastTimestamp)
                timestamp = now;
            else
                timestamp = LastTimestamp.AddSeconds(1);
            LastTimestamp = timestamp;
        }
        return timestamp;
    }
}
于 2012-12-19T10:05:23.440 に答える
1

2つのタスクが同じ秒内に実行される場合、ファイル名は一意ではありません。解決策は、グローバルな(おそらく静的な)数値ジェネレーターを持つことです。

public static class NumberGenerator
{
    static object syncObject = new Object();
    static int nextNr = 0;
    public static int NextNumber
    {
        get
        { 
            lock (syncObject)
            {
                nextNr++;
                return nextNr;
            }
        }
    }
}

string filename = NumberGenerator.NextNumber + ".txt";
于 2012-12-19T08:25:22.670 に答える
0

Task.CurrentIdプロパティをファイル名に組み込むことができます。

于 2012-12-19T08:58:51.197 に答える