سؤال

هل هناك مولد رقم متسلسل على مستوى النظام المدار؟ DateTime.Now.ticks لن تفعل لأن العمليات التي أقوم بها في بعض الأحيان تحدث أكثر من مرة لكل علامة.


توضيحات الشرط:

  • عملية الأذرع - هناك بالفعل عملية واحدة فقط من شأنها الوصول إلى هذا.
  • الأداء أمر بالغ الأهمية! يستخدم هذا لتسجيل الانطباعات على ADSERVER، والتي يمكن أن تصل إلى 1K / ثانية

سيحتاج إلى أن يكون واحدا مما يلي:

  • رقم متسلسل 4 بايت يعيد تعيين كل علامة
  • الرقم التسلسلي 12 بايت - إضافة أساسا 4 بايت من الحبيبية إلى DateTime
هل كانت مفيدة؟

المحلول

لا شيء مخصص لهذا، ولكن يمكنك استخدام system.diagnostics.performancounter.. وبعد يمكنك أيضا استخدام السجل ولكنك تحتاج إلى تسلسل Awr / الكتابة Access Accrross العمليات.

System.Diagnostics.PerformanceCounter pc 
    = new System.Diagnostics.PerformanceCounter("SeqCounter", "SeqInstance");
long myVal=pc.Increment();

يحرر

كلما أفكر في هذا الأمر، أعتقد أن هذا قد يكون حل لطيف. سيزيد الزيادة من العداد بنسبة 1 من خلال عملية ذرية يجب أن تعمل جميع العمليات على نظام.

يحرر

بناء على تعديلاتك، لن أوصي باستخدام عداد الأداء. كان عداد الأداء وسيلة للتخلص من عمليات متعددة. لست متأكدا من كيفية ترميز التنفيذ الداخلي.

لماذا لا يمكنك فقط استخدام متغير ثابت وزيادة ذلك؟ سوف تضطر إلى قفل شيء إذا كنت تريد هذا أن يكون الخلاف.

system.threading.inklocked.incrent.

FYI: إذا كنت تستخدم النسخة الطويلة على نظام 32 بت، فلن يكون NESSECARILLY خيط آمنا.


التحرير لإظهار الانفان الذي استخدمته (DS):

public static class Int32Sequencer
{
    private static Int32 lastSequence = Int32.MinValue;
    private static Object lockObject = new Object();
    public static Int32 GetNextSequence()
    {
        lock (lockObject)
        {
            unchecked { lastSequence++; }
            return lastSequence;
        }
    }
}

نصائح أخرى

GUID هو أقرب ما ستحصل عليه، لكن تلك هي "فريدة" وغير متتابعة بالضرورة. إذا كنت تريد حقا متتابعا عبر عمليات متعددة على مستوى النظام، فمن المحتمل أن تضطر إلى لفة خاصة بك.

تعديل:

حسنا، من المتطلبات الجديدة الخاصة بك، سأفترض:

  1. تحتاج عملية واحدة فقط إلى القيام بالعمل
  2. أنت إلحاق بقاعدة بيانات

حتى هنا هو ما أوصي به:

  1. عند بدء تشغيل العملية، استفسر DB للقيمة الأخيرة (أعظم) (0 إذا لم يكن أي منها موجودا).
  2. استخدم طويلا بسيطا وزيادة لكل صف DB. سوف ترغب في إدراج على دفعات بسبب ارتفاع معدل البيانات الخاص بك.

يجب أن تفعل ذلك. أبقيها بسيطة. هذا لا يوجد لديه أقفال، ضئيل (ضئيل) ضرب عند بدء التشغيل، والأرقام المتسلسلة في DB. هذه الخوارزمية هي أيضا معالجة المعالجة اللاإرادية طالما لديك سوى عملية واحدة تديرها.

أعتقد أن أقرب شيء هو GUID، كما أنا متأكد من أنك تدرك في أحسن الأحوال متتالية جزئيا فقط.

هناك مقال هنا يعطي بعض التفاصيل لخادم SQL:GUID المتسلسل في SQL Server تستخدم هذه التقنية لتقليل تقسيم الصفحات بسبب العشوائية في GUID. ربما هذا الرابط سوف يعطيك بعض التلميحات أو الأفكار.

أعتقد أننا بحاجة إلى معرفة المزيد عن ما تبحث عنه. هل يمكنك توضيح سؤالك قليلا. على وجه الخصوص هل الخدمة ...

  • بحاجة إلى العمل عبر جميع العمليات أو عملية واحدة أو مستخدم معين؟
  • يجب أن تكون الأرقام فريدة أو متتالية فقط؟

بناء على سؤالك، يبدو أن هناك بضع عناصر مختلفة قد تبحث عنها.

بحاجة إلى مجموعة متتابعة من الأرقام عبر جميع العمليات على النظام

afaik، لا توجد هذه الخدمة موجودة. يجب أن يكون المرء من السهل إلى حد ما الكتابة ولكن الحصول عليه للعمل عبر جميع العمليات أمر صعب.

بحاجة إلى مجموعة متتابعة فريدة من الأرقام عبر جميع العمليات على النظام

تباين طفيف في السؤال الأول. هذه الخدمة غير موجودة لأنه سيكون من المستحيل تنفيذها. لا توجد وسيلة لضمان رقم متتابع فريد باستخدام أنواع البيانات المدمجة ببساطة لأن القيمة ستثير في نهاية المطاف وتركك برقم مكرر.

بحاجة إلى طريقة للحصول على القيم الفريدة في النظام

نظرا لأن العديد من المستخدمين الآخرين قد ذكروا أفضل خيار هو مثيل System.guid. يمكنك إنشاء واحدة جديدة باستخدام guid.newguid (). بالنسبة لجميع الأغراض تقريبا، يمكن اعتبارها فريدة من نوعها ولكنها ليست متتالية.

أنا أحب خيار قاعدة البيانات ببساطة للسلامة. تأكد من تثبيت خادم Monster SQL مع خصائص عرض النطاق الترددي بين الخوادم الخاصة بك مع ذاكرة كافية على الرغم من ذلك. تم تنفيذ نظام مشابه لهذا العام في الشركة الأولى التي عملت فيها من أي وقت مضى (قبل أن أصبحت مبرمجة) وكانت مراوغة جدا. قد تقاتل لتوسيع نطاق هذا.

سيكون هناك خيار آخر هو تطبيق وظيفة Singleton في التعليمات البرمجية الخاصة بك ... شريطة أن يتم الاتصال به مجال تطبيق واحد فقط. قد يكون أسرع قليلا من القيام برحلة قاعدة البيانات. إذا كنت ستسجيل هذه الأشياء إلى قاعدة البيانات على أي حال .... ماذا عن الجمع بين الاثنين ... قم بتشغيل Singleton للسرعة ثم الكتابة إلى قاعدة البيانات عند تصريح الموارد.

مرة أخرى، إذا لم يكن الشرط المتسلسل ذلك قويا، فسيكون GUID أفضل رهان.

لا توجد طريقة للحصول على سلسلة متتالية واحدة دون قفل. لا يهم الآلية التي تستخدمها لتعيين القيمة التالية - عداد الأداء، ومتغير ثابت، أيا كان - عندما يحتاج كل من الخيوط إلى القيمة التالية في نفس الوقت، على المرء الانتظار من هنا.

أول شيء كنت أفعله هو كتابة برنامج اختبار تم طرح عدد كبير من الخيوط التي تسمى كل منها مرارا وتكرارا وظيفة زيادة القفل مثل Daniel Schaffer المنشورة. سيتيح لك ذلك العثور على العتبة حيث يبدأ طلبك في السحق - حيث ينفق المزيد من الوقت في انتظار Monitor.Enter من فعل أي شيء آخر.

إذا اتضح أن هذا يمثل مشكلة - وأراه أنه إذا كانت وحدات التخزين التي تتحدث عنها حقيقية، فستفعل - ثم يجب أن تجعل كل مؤشر ترابط يحافظ على عداده المتسلسل الخاص به، والذي يمكنك القيام به عن طريق وضع علامة على حقل العداد مع ال ThreadStaticAttribute. وبعد يمكنك بعد ذلك إنشاء معرفات فريدة من نوعها من مزيج من معرف الخيط والعداد.

لن يعمل هذا النهج إذا كنت لا تستخدم تجمع مؤشر ترابط (نظرا لأن العداد يموت عندما ينتمي الموضوع إليه). وربما تريد أيضا إجراء جزء بدء تشغيل التطبيق من معرف المركب، بحيث لا يتعين عليك كتابة عدادات الخيط إلى تخزين دائم. (إذا لم تقم بذلك، عند إعادة تشغيل الخادم، ستبدأ مؤشرات الترابط في إنشاء عدادات عند الصفر مرة أخرى، وإذا قام طلبك بإنشاء مؤشر ترابط بنفس المعرف مثل مثيل سابق، فستحصل على معرفات مكررة.)

من الواضح أن هذا غير تافه للكتابة (أو، والأهم من ذلك، اختبار)، لذلك أود أن أوصي بالتأكيد بالإثبات أنه من الضروري أولا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top