2

我正在使用任务将多个文件上传到 sftp 服务器。但是目前正在发生的是,当多个任务并行执行时,会生成相同的“文件名”。我想确保每次都生成一个不同的文件名。

//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如果尚未返回此时间,则返回,否则返回未来的第一个空闲秒。

这样,你会得到一个少量不正确的时间戳(或者大量不正确,如果你长时间每秒多次调用此方法),但这意味着你不必等待,感觉对我来说很脆弱。

在代码中:

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

如果两个任务在同一秒内执行,则文件名将不唯一。一个解决方案是拥有一个全局(可能是静态的)数字生成器。

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 回答