2012-12-19 27 views
2

使用不同文件名的TPL我使用任務將多個文件上傳到sftp服務器。但是目前發生的情況是,當多個任務並行執行時,會生成相同的「文件名」。我想確保每次都生成一個獨特的文件名。使用Datetime.Now

//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); 
    }); 
} 

回答

1

您可以使用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; 
    } 
} 
+0

太棒了。這工作,是比我使用的thread.Sleep(1000)更快的解決方案。 – Saad

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"; 
+0

我必須有一個與** [日期時間]的.txt **種類格式即** ** 20121219021320.txt(yyyyMMddHHmmss.txt),所以我不能改變的文件名文件名格式。我只能確保文件名中的秒數有所不同。 鎖定,在我的代碼1秒Thread.Sleep()確保? – Saad

+0

+1:但Saad評論說,可能需要Thread.Sleep(1000)。 –

0

您可以將Task.CurrentId屬性合併到您的文件名中。

+0

上傳的文件正在被另一個系統使用,並且這兩個系統具有約定的fileName格式,即** 20121219021320.txt **(yyyyMMddHHmmss.txt),所以我無法更改文件名格式。 我只能確保文件名中的秒數不同,並且我正在尋找一種方法來執行此操作。 – Saad