Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用DateTime.Now.Ticks生成唯一的数字ID_C#_.net_Multithreading_Algorithm_Concurrency - Fatal编程技术网

C# 使用DateTime.Now.Ticks生成唯一的数字ID

C# 使用DateTime.Now.Ticks生成唯一的数字ID,c#,.net,multithreading,algorithm,concurrency,C#,.net,Multithreading,Algorithm,Concurrency,我需要生成一个唯一的数字ID以附加到传入请求。此ID仅临时用于跟踪请求,并且在请求完成处理后将被丢弃。此ID仅在该应用程序的上下文中使用,但需要以高性能多线程方式分配 我正在考虑使用DateTime.Now.Ticks作为此ID,但想知道如果同时处理请求,DateTime.Now.Ticks是否仍然可以生成冲突ID 如果有人能建议一种更好的方法在多线程环境中生成这些ID(最好不是像Tick那样的Int64),请告诉我。像递增数字这样简单的东西就足够了,只要我不必在递增之前锁定数字就行了 非常感谢

我需要生成一个唯一的数字ID以附加到传入请求。此ID仅临时用于跟踪请求,并且在请求完成处理后将被丢弃。此ID仅在该应用程序的上下文中使用,但需要以高性能多线程方式分配

我正在考虑使用DateTime.Now.Ticks作为此ID,但想知道如果同时处理请求,DateTime.Now.Ticks是否仍然可以生成冲突ID

如果有人能建议一种更好的方法在多线程环境中生成这些ID(最好不是像Tick那样的Int64),请告诉我。像递增数字这样简单的东西就足够了,只要我不必在递增之前锁定数字就行了


非常感谢您的帮助。

只需获取一个强随机数或使用GUID即可


如果高性能是必须具备的特性,则按单调顺序分配序列号。通过为每个处理消息的线程“保留”一个范围(例如,20-100)的ID来防止锁争用。这样,您只需在20-100次迭代中锁定序列生成器一次。

从每个线程ID(如果多个线程发起请求)开始,并连接一个每个线程计数器(如果每个线程预期发起多个请求)。

DateTime。现在对于这个目的来说,
是绝对糟糕的。充其量,分辨率为1毫秒;在最坏的情况下,NT为17毫秒,CE/Compact框架为1秒(!)


考虑对快速、线程安全的计数器使用方法。

您只需要使用一个静态变量,该变量在每次需要另一个唯一值时递增。您可以使用以下方法使此线程安全且仍然非常快速

// Declaration
private static int safeInstanceCount = 0;

// Usage
{
      ...
      Interlocked.Increment(ref safeInstanceCount);
      ...
}

如果您知道将有多少个线程(或者至少有一个上限),您可以在线程之间划分ID空间,将ID计算为(线程本地)计数器的值和线程的ID-例如,
counter_value++可以使用此属性,但支付1ms,这并不重要

public static long UniqId { 
    get { 
        Thread.Sleep(1); 
        return long.Parse(DateTime.Now.ToString("yyMMddHHmmssffff")); 
    } 
}

我已经在考虑interlock.increment,但我希望避免任何类型的锁。但是,正如您所提到的,性能影响可能可以忽略不计,因此我可能会继续这样做,而不是在优化上花费太多的时间。谢谢。性能影响不值得考虑,除非您计划每分钟调用数百万次。另外,它非常易于使用。@PhilWright:在我的linux机器上
time csharp但是,当线程化时,性能会下降:
ThreadStart a=()=>{int x=0;而(Interlocked.Increment(ref x)<100000000);}并行x 4需要9秒;共享
int x
(通过将其从lambda中取出)需要32秒(仅约31 miljon incr/s)——而对interlocated.Increment的总调用数实际上是小的4倍:)有趣的反馈。我怀疑interlock.increment所花费的时间与使用它执行的实际操作时间相比是很小的。使用GUID/UUID有什么问题?生成GUID的开销太大。我需要的ID只需要对流程是唯一的(不是全局的),并且它只用于每个请求的持续时间。“开销太大”?GUID只需要生成几个字节的随机数据。不贵。听起来你在进行过早的优化。可能这在实际时间内无关紧要,但从一些基本测试来看,它看起来比interlocked慢10倍左右。增加8个并发线程。如果你生成了足够重要的ID,那就够公平了。使用random看起来可能是“随机的”性能是必须的,这就是为什么我避开guid或者必须计算ID。为每个线程保留一系列ID是一个好主意。我会仔细考虑一下。谢谢。@KirkWoll:如果random够随机的话就不用了。由于这个原因,可以假定GUID不会冲突,这一点已被广泛接受。说:“一毫秒内有10000个滴答声。”@PeterX 1滴答声=100ns的定义绝不意味着
DateTime的实现;我遇到了我在帖子中提到的所有实现限制。如果你真的需要微秒级精度,那就做得更好。不用担心-是的,我已经转到了
Guid
,只是为了确保我的临时文件夹(无论如何都会清理)是唯一的。