我正在使用任务将多个文件上传到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);
});
}
答案 0 :(得分: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";
答案 1 :(得分: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;
}
}
答案 2 :(得分:0)
您可以将Task.CurrentId属性合并到您的文件名中。