c# - 随机数在不同进程中与相同的 .Net 代码发生冲突

标签 c# .net multithreading random multicore

在开始之前,我想指出,我非常确定这确实发生了。我所有的日志都表明确实如此。

我想知道我是否错了,这是不可能的,是否只是难以置信地不可能(我怀疑),或者如果不是那么不可能,我做的事情从根本上是错误的。

我在同一台服务器上有 4 个相同代码的实例作为 Windows 服务运行。此服务器具有多核 (4) 处理器。

这里是代码的总结:

public class MyProcess
{
    private System.Timers.Timer timer;

    // execution starts here
    public void EntryPoint()
    {
        timer = new System.Timers.Timer(15000);  // 15 seconds
        timer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed);
        timer.AutoReset = false;

        Timer_Elapsed(this, null);
    }

    private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        string uid = GetUID();

        // this bit of code sends a message to an external process.
        //  It uses the uid as an identifier - these shouldn't clash!
        CommunicationClass.SendMessage(uid);

        timer.Start();
    }

    // returns an 18 digit number as a string
    private string GetUID()
    {
        string rndString = "";
        Random rnd = new Random((int)DateTime.Now.Ticks);
        for (int i = 0; i < 18; i++)
        {
            rndString += rnd.Next(0, 10);
        }
        return rndString;
    }

接收这些消息的外部进程感到困惑 - 我认为是因为相同的 uid 来自两个不同的进程。基于此,看来 GetUID()方法为两个单独的进程返回相同的“随机”18 位字符串。

我已经使用 DateTime.Now.Ticks 为 Random 类播种,我认为它可以在线程之间提供保护 - 一个滴答为 100 纳秒,两个线程肯定无法获得相同的种子值。

我显然没有考虑到的是,我们不是在谈论线程,我们是在谈论多核处理器上的进程。这意味着这段代码可以字面上同时运行两次。我认为这就是导致冲突的原因。

以大约 15 秒的间隔运行相同代码的两个进程设法在 100 纳秒内命中相同的代码。这可能吗?我走在正确的轨道上吗?

如果您有任何想法或建议,我将不胜感激。


澄清一下,我不能真正使用 GUID - 与我通信的外部进程需要一个 18 位数字。它很旧,很遗憾我无法更改它。

最佳答案

除非有某些原因你不能,否则你应该考虑使用 GUID以此目的。您将以这种方式消除碰撞。

根据评论:您可以使用 GUID 和 64 位 FNV hash并使用 XOR-folding使您的结果在您拥有的 59 位以内。不像 GUID 那样防碰撞,但比您拥有的更好。

关于c# - 随机数在不同进程中与相同的 .Net 代码发生冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1134738/

相关文章:

multithreading - servlet多线程

java - 修改线程类中的 HashMap 时出现 ConcurrentModificationException

c# - RegisterWaitForSingleObject 未定义行为与 ManualResetEvent

c# - SQL Server CLR 线程

c# - 从 WCF 发送的响应中删除 utf-8 标识符 (BOM)

c# - WPF 应用程序启动时间太长

c# - 如何在 dotnet 应用程序中创建导航菜单?

c# - UWP 后台任务错误

c# - 为什么将事件处理程序复制到另一个变量中

c# - C#中的FTP客户端