ΠΠ°ΠΌΠ΅ΡΠ°Π½ΠΈΠ΅. ΠΡΠ»ΠΈ ΠΏΡΡΠ°ΡΡΡΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠΉ ΠΊΠΎΠ΄ Π² ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠΌ ΠΌΠ΅ΡΠΎΠ΄Π΅, Π²Ρ, ΠΎΡΠ΅Π²ΠΈΠ΄Π½ΠΎ, Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΊΠ»ΡΡΠ΅Π²ΠΎΠ΅ ΡΠ»ΠΎΠ²ΠΎ this. ΠΠΎ Π² ΡΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ System.Type ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π³ΠΎ ΠΊΠ»Π°ΡΡΠ° Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° C# typeof.
ΠΡΠ»ΠΈ ΡΠ½ΠΎΠ²Π° Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ ΡΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π²Ρ ΡΠ²ΠΈΠ΄ΠΈΡΠ΅, ΡΡΠΎ ΡΠ΅ΠΏΠ΅ΡΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΏΠΎΡΠΎΠΊ ΠΏΠΎΠ»ΡΡΠ°Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π·Π°ΠΊΠΎΠ½ΡΠΈΡΡ ΡΠ²ΠΎΡ ΡΠ°Π±ΠΎΡΡ (ΡΠΈΡ. 14.10).
Π ΠΈΡ. 14.10. ΠΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠΈΡ Π² Π΄Π΅ΠΉΡΡΠ²ΠΈΠΈ, ΡΡΠ΅ΡΡΡ ΠΏΠΎΠΏΡΡΠΊΠ°
ΠΡΡ ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄. ΠΡΠΎΠ΅ΠΊΡ MultiThreadedPrinting ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½ Π² ΠΏΠΎΠ΄ΠΊΠ°ΡΠ°Π»ΠΎΠ³Π΅, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅ΠΌ Π³Π»Π°Π²Π΅ 14.
Π‘ΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠΈΠΏΠ° System.Threading.Monitor
ΠΠΏΠ΅ΡΠ°ΡΠΎΡ C# lock Π½Π° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅ ΡΠ²Π»ΡΠ΅ΡΡΡ Π»ΠΈΡΡ ΠΊΠ»ΡΡΠ΅Π²ΡΠΌ ΡΠ»ΠΎΠ²ΠΎΠΌ, ΠΎΠ±ΠΎΠ·Π½Π°ΡΠ°ΡΡΠΈΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠΈΠΏΠ° ΠΊΠ»Π°ΡΡΠ° System.Threading.Monitor. ΠΠΎΡΠ»Π΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠΎΠΌ C# ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ ΠΏΡΠ΅Π²ΡΠ°ΡΠ°Π΅ΡΡΡ Π² ΡΠ»Π΅Π΄ΡΡΡΠ΅Π΅ (Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠ±Π΅Π΄ΠΈΡΡΡΡ Π² ΡΡΠΎΠΌ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ildasm.exe).
public void PrintNumbers() {
Monitor.Enter(this);
try {
// ΠΡΠ·ΠΎΠ² ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ Thread.
Console.WriteLine("-βΊ {0} Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ PrintNumbers()", Thread.CurrentThread.Name); // ΠΡΠ²ΠΎΠ΄ ΡΠΈΡΠ΅Π».
Console.Write("ΠΠ°ΡΠΈ ΡΠΈΡΠ»Π°: ");
for (int i = 0; i βΉ 10; i++) {
Random r = new Random();
Thread.Sleep(1000* r.Next(5));
Console.Write(i + ", ");
}
Console.WriteLine();
} finallΡ {
Monitor.Exit(this);
}
}
ΠΠΎ-ΠΏΠ΅ΡΠ²ΡΡ , Π·Π°ΠΌΠ΅ΡΠΈΠΌ, ΡΡΠΎ ΠΊΠΎΠ½Π΅ΡΠ½ΡΠΌ ΠΏΠΎΠ»ΡΡΠ°ΡΠ΅Π»Π΅ΠΌ ΠΌΠ°ΡΠΊΠ΅ΡΠ° ΠΏΠΎΡΠΎΠΊΠ°, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ» ΡΠΊΠ°Π·Π°Π½ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ° ΠΊΠ»ΡΡΠ΅Π²ΠΎΠ³ΠΎ ΡΠ»ΠΎΠ²Π° lock, ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΌΠ΅ΡΠΎΠ΄ Monitor.Enter(). ΠΠΎ-Π²ΡΠΎΡΡΡ , Π²Π΅ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠΉ ΠΊΠΎΠ΄ Π² ΡΠ°ΠΌΠΊΠ°Ρ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅ΠΉ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ ΠΏΠΎΠΌΠ΅ΡΠ΅Π½ Π² Π±Π»ΠΎΠΊ try. Π‘ΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ Π±Π»ΠΎΠΊ finally Π³Π°ΡΠ°Π½ΡΠΈΡΡΠ΅Ρ, ΡΡΠΎ ΠΌΠ°ΡΠΊΠ΅Ρ ΠΏΠΎΡΠΎΠΊΠ° Π±ΡΠ΄Π΅Ρ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π΅Π½ (Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Π° Monitor.Exit()), Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎ ΠΎΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠ³ΡΡ Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡΡ Π² ΡΡΠ΅Π΄Π΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ. ΠΡΠ»ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ MultiThreadSharedData ΡΠ°ΠΊ, ΡΡΠΎΠ±Ρ ΡΠΈΠΏ Monitor ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΡΡ Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ (ΠΊΠ°ΠΊ ΡΡΠΎ Π±ΡΠ΄Π΅Ρ ΡΠ΄Π΅Π»Π°Π½ΠΎ ΡΡΡΡ ΠΏΠΎΠ·ΠΆΠ΅), ΡΠΎ Π΅Π΅ Π²ΡΠ²ΠΎΠ΄ ΠΎΡΡΠ°Π½Π΅ΡΡΡ ΡΠ΅ΠΌ ΠΆΠ΅.
ΠΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΠΊΠ»ΡΡΠ΅Π²ΠΎΠ³ΠΎ ΡΠ»ΠΎΠ²Π° lock, ΠΊΠ°ΠΆΠ΅ΡΡΡ, ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΠΌΠ΅Π½ΡΡΠΈΠΉ Π²Π²ΠΎΠ΄ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°, ΡΠ΅ΠΌ ΠΏΡΠΈ ΡΠ²Π½ΠΎΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΉ ΡΠΈΠΏΠ° System.Threading.Monitor, ΠΏΠΎΡΡΠΎΠΌΡ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π·Π°Π΄Π°ΡΡ Π²ΠΎΠΏΡΠΎΡ ΠΎ ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ²Π°Ρ Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎΠ³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΡΠΈΠΏΠ° Monitor. ΠΡΠ°ΡΠΊΠΈΠΉ ΠΎΡΠ²Π΅Ρ: ΠΊΠΎΠ½ΡΡΠΎΠ»Ρ. ΠΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΡΠΈΠΏΠ° Monitor Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π°ΡΡ ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ Π°ΠΊΡΠΈΠ²Π½ΠΎΠΌΡ ΠΏΠΎΡΠΎΠΊΡ ΠΏΠΎΠ΄ΠΎΠΆΠ΄Π°ΡΡ (Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Π° Wait()), ΠΈΠ½ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°ΡΡ ΠΎΠΆΠΈΠ΄Π°ΡΡΠΈΠ΅ ΠΏΠΎΡΠΎΠΊΠΈ ΠΎ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠΈ ΡΠ΅ΠΊΡΡΠ΅Π³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° (Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² Pulse() ΠΈ PulseAll()) ΠΈ Ρ.Π΄.
Π Π±ΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²Π΅ ΡΠ»ΡΡΠ°Π΅Π² Π²Π°ΠΌ Π±ΡΠ΄Π΅Ρ Π²ΠΏΠΎΠ»Π½Π΅ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠ΅ΠΉ, ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅ΠΌΡΡ ΠΊΠ»ΡΡΠ΅Π²ΡΠΌ ΡΠ»ΠΎΠ²Π°ΠΌ C# lock. ΠΠΎ Π΅ΡΠ»ΠΈ Π²Ρ Π·Π°Ρ ΠΎΡΠΈΡΠ΅ ΡΠ°ΡΡΠΌΠΎΡΡΠ΅ΡΡ Π΄ΡΡΠ³ΠΈΠ΅ ΡΠ»Π΅Π½Ρ ΠΊΠ»Π°ΡΡΠ° Monitor, ΠΎΠ±ΡΠ°ΡΠΈΡΠ΅ΡΡ ΠΊ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ .NET Framework 2.0 SDK.
Π‘ΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠΈΠΏΠ° System.Threading.Interlocked
Π ΡΡΠΎ Π²ΡΠ΅Π³Π΄Π° Π²Π΅ΡΠΈΡΡΡ Ρ ΡΡΡΠ΄ΠΎΠΌ, ΠΏΠΎΠΊΠ° Π²Ρ Π½Π΅ ΠΏΡΠΎΠ²Π΅ΡΠΈΡΠ΅ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠΉ ΠΊΠΎΠ΄ CIL, Π½ΠΎ ΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΠΏΡΠΈΡΠ²Π°ΠΈΠ²Π°Π½ΠΈΡ, ΠΈ Π±Π°Π·ΠΎΠ²ΡΠ΅ Π°ΡΠΈΡΠΌΠ΅ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ Π½Π΅ ΡΠ²Π»ΡΡΡΡΡ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΠΌΠΈ. ΠΠΎΡΡΠΎΠΌΡ Π² ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π΅ ΠΈΠΌΠ΅Π½ System.Threading ΠΏΡΠ΅Π΄Π»Π°Π³Π°Π΅ΡΡΡ ΡΠΈΠΏ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠΈΠΉ Π²ΠΎΠ·Π΄Π΅ΠΉΡΡΠ²ΠΎΠ²Π°ΡΡ Π½Π° ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ Π΄Π°Π½Π½ΡΡ Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎ Ρ ΠΌΠ΅Π½ΡΡΠ΅ΠΉ Π½Π°Π³ΡΡΠ·ΠΊΠΎΠΉ, ΡΠ΅ΠΌ ΡΡΠΎ Π΄Π΅Π»Π°Π΅Ρ ΡΠΈΠΏ Monitor. Π’ΠΈΠΏ ΠΊΠ»Π°ΡΡΠ° Interlocked ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ»Π΅Π½Ρ, ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ ΠΊΠΎΡΠΎΡΡΡ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Ρ Π² ΡΠ°Π±Π». 14.4.
Π’Π°Π±Π»ΠΈΡΠ° 14.4. Π§Π»Π΅Π½Ρ ΡΠΈΠΏΠ° System.Threading.Interlocked
Π§Π»Π΅Π½ ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ CompareExchange() ΠΠ΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ Π΄Π²Π° Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π½Π° ΡΠ°Π²Π΅Π½ΡΡΠ²ΠΎ, ΠΈ Π΅ΡΠ»ΠΈ ΠΎΠ½ΠΈ ΡΠ°Π²Π½Ρ, Π·Π°ΠΌΠ΅Π½ΡΠ΅Ρ ΠΎΠ΄Π½ΠΎ ΠΈΠ· Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ ΡΡΠ΅ΡΡΠΈΠΌ Decrement() ΠΠ΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ ΡΠΌΠ΅Π½ΡΡΠ°Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π½Π° 1 Exchange() ΠΠ΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ ΠΌΠ΅Π½ΡΠ΅Ρ Π΄Π²Π° Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΌΠ΅ΡΡΠ°ΠΌΠΈ Increment() ΠΠ΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ ΠΏΡΠΈΡΠ°ΡΠ΅Π½ΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π½Π° 1Π₯ΠΎΡΡ ΡΡΠΎ ΠΌΠΎΠΆΠ΅Ρ ΠΈ Π½Π΅ ΠΊΠ°Π·Π°ΡΡΡΡ ΠΎΡΠ΅Π²ΠΈΠ΄Π½ΡΠΌ Π½Π° ΠΏΠ΅ΡΠ²ΡΠΉ Π²Π·Π³Π»ΡΠ΄, ΠΏΡΠΎΡΠ΅ΡΡ Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎΠ³ΠΎ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΡΠ²Π»ΡΠ΅ΡΡΡ Π²ΠΏΠΎΠ»Π½Π΅ ΡΠΈΠΏΠΈΡΠ½ΡΠΌ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΠΌ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠΈ. ΠΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, ΡΡΠΎ Ρ Π½Π°Ρ Π΅ΡΡΡ ΠΌΠ΅ΡΠΎΠ΄ AddOne(), ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅Ρ ΡΠ΅Π»ΠΎΡΠΈΡΠ»Π΅Π½Π½ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ intVal Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡΡ. ΠΠΌΠ΅ΡΡΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ³ΠΎ ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌΡ;
public void AddOne() {
lock(this) {
intVal++;
}
}
ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠΈΡΡ Π±ΠΎΠ»Π΅Π΅ ΠΏΡΠΎΡΡΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠΉ ΠΊΠΎΠ΄, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΌΠ΅ΡΠΎΠ΄ Interlocked.Increment(). ΠΡΠΎΡΡΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΠΉΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ Π΄Π»Ρ ΠΏΡΠΈΡΠ°ΡΠ΅Π½ΠΈΡ ΠΏΠΎ ΡΡΡΠ»ΠΊΠ΅. ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΡΠΎ, ΡΡΠΎ ΠΌΠ΅ΡΠΎΠ΄ Increment() Π½Π΅ ΡΠΎΠ»ΡΠΊΠΎ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎΡΡΡΠΏΠ°ΡΡΠ΅Π³ΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°, Π½ΠΎ ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π½ΠΎΠ²ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅.
public void AddOne() {
int newVal = Interlocked.Increment(ref intVal);
}
Π Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊ Increment() ΠΈ Decrement() ΡΠΈΠΏ Interlocked ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎ ΠΏΡΠΈΡΠ²Π°ΠΈΠ²Π°ΡΡ ΡΠΈΡΠ»ΠΎΠ²ΡΠ΅ ΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠ½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π΅ΡΠ»ΠΈ Π²Ρ Ρ ΠΎΡΠΈΡΠ΅ ΠΏΡΠΈΡΠ²ΠΎΠΈΡΡ ΡΠ»Π΅Π½Ρ-ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ 83, Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ ΡΠ²Π½ΠΎΠ³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° lock (ΠΈΠ»ΠΈ ΡΠ²Π½ΠΎΠ³ΠΎ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡ Π»ΠΎΠ³ΠΈΠΊΠΈ Monitor), Π΅ΡΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄ Interlocked.Exchange().
public void SafeAssignment() {
Interlocked.Exchange(ref myInt, 83);
}
ΠΠ°ΠΊΠΎΠ½Π΅Ρ, ΠΏΡΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ΅ Π΄Π²ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ Π½Π° ΡΠ°Π²Π΅Π½ΡΡΠ²ΠΎ, ΡΡΠΎΠ±Ρ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΡΡ ΠΏΠΎΡΠΎΠΊΠΎΠ²ΡΡ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ, ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ Interlocked.CompareExchange(), ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½ΠΈΠΆΠ΅.
public void CompareAndExchange() {
// ΠΡΠ»ΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ i ΡΠ²Π»ΡΠ΅ΡΡΡ 83, ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ Π΅Π³ΠΎ Π½Π° 99.
Interlocked.CompareExchange(ref i, 99, 83);
}
Π‘ΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π°ΡΡΠΈΠ±ΡΡΠ° [Synchronization]
ΠΠΎΡΠ»Π΅Π΄Π½ΠΈΠΌ ΠΈΠ· ΡΠ°ΡΡΠΌΠΎΡΡΠ΅Π½Π½ΡΡ Π·Π΄Π΅ΡΡ ΠΏΡΠΈΠΌΠΈΡΠΈΠ²ΠΎΠ² ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ Π±ΡΠ΄Π΅Ρ Π°ΡΡΠΈΠ±ΡΡ [Synchronization], ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΡΡΡ Π² ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π΅ ΠΈΠΌΠ΅Π½ System.Runtime.Remoting.Contexts. ΠΡΠΎΡ Π°ΡΡΠΈΠ±ΡΡ ΡΡΠΎΠ²Π½Ρ ΠΊΠ»Π°ΡΡΠ° Π΄Π»Ρ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ ΠΏΠΎΡΠΎΠΊΠ° ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎ Π±Π»ΠΎΠΊΠΈΡΡΠ΅Ρ Π²Π΅ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠΉ ΠΊΠΎΠ΄ ΡΠ»Π΅Π½ΠΎΠ² ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°. ΠΠΎΠ³Π΄Π° ΡΡΠ΅Π΄Π° CLR ΡΠ°Π·ΠΌΠ΅ΡΠ°Π΅Ρ ΠΎΠ±ΡΠ΅ΠΊΡ, ΠΈΠΌΠ΅ΡΡΠΈΠΉ Π°ΡΡΠΈΠ±ΡΡ [Synchronization], ΠΎΠ½Π° ΠΏΠΎΠΌΠ΅ΡΠ°Π΅Ρ ΡΡΠΎΡ ΠΎΠ±ΡΠ΅ΠΊΡ Π² ΡΠ°ΠΌΠΊΠΈ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ°. ΠΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΠΎΠΌΠ½ΠΈΡΡ ΠΈΠ· Π³Π»Π°Π²Ρ 13, ΡΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΠΎΠΊΠΈΠ΄Π°ΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ½ΡΠ΅ Π³ΡΠ°Π½ΠΈΡΡ, ΡΠ²Π»ΡΡΡΡΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΡΠΌΠΈ ΠΎΡ ContextBoundObject. ΠΠΎΡΡΠΎΠΌΡ, ΡΡΠΎΠ±Ρ ΡΠ΄Π΅Π»Π°ΡΡ ΡΠΈΠΏ ΠΊΠ»Π°ΡΡΠ° Printer ΡΡΡΠΎΠΉΡΠΈΠ²ΡΠΌ Π² ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠΈ ΠΏΠΎΡΠΎΠΊΠΎΠ² (Π±Π΅Π· Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° Π·Π°ΡΠΈΡΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² Π²ΡΡΡΠ½ΡΡ), ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΡΠ°ΠΊ.
using System.Runtime.Remoting.Contexts;
...
// ΠΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄Ρ Printer ΡΠ΅ΠΏΠ΅ΡΡ ΠΏΠΎΡΠΎΠΊΠΎΡΡΡΠΎΠΉΡΠΈΠ²Ρ!
[Synchronization]
public class Printer: Π‘ontextBoundObject {
public void PrintNumbers() {
β¦
}
}
ΠΡΠΎΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°Π·Π²Π°ΡΡ ΡΠΏΠΎΡΠΎΠ±ΠΎΠΌ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΡΡΡΠΎΠΉΡΠΈΠ²ΠΎΠ³ΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° Π΄Π»Ρ Π»Π΅Π½ΠΈΠ²ΡΡ , ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π·Π΄Π΅ΡΡ Π½Π΅ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π²ΡΡΡΠ½ΡΡΡ, ΠΊΠ°ΠΊΠΈΠ΅ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΡ ΡΠΈΠΏΠ° ΠΌΠΎΠ³ΡΡ ΠΈΡΠΏΡΡΡΠ²Π°ΡΡ Π²Π»ΠΈΡΠ½ΠΈΠ΅ Π²Π½Π΅ΡΠ½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ². ΠΠ»Π°Π²Π½ΡΠΌ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΊΠΎΠΌ ΡΡΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ ΠΎΠ΄Π° ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΎ, ΡΡΠΎ Π΄Π°ΠΆΠ΅ Π΅ΡΠ»ΠΈ ΠΊΠ°ΠΊΠΎΠΉ-ΡΠΎ ΠΌΠ΅ΡΠΎΠ΄ ΠΈ Π½Π΅ ΠΈΡΠΏΡΡΡΠ²Π°Π΅Ρ Π²Π»ΠΈΡΠ½ΠΈΡ Π²Π½Π΅ΡΠ½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ², ΡΡΠ΅Π΄Π° CLR Π²ΡΠ΅ ΡΠ°Π²Π½ΠΎ Π±Π»ΠΎΠΊΠΈΡΡΠ΅Ρ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΠΊ ΡΡΠΎΠΌΡ ΠΌΠ΅ΡΠΎΠ΄Ρ. ΠΡΠ΅Π²ΠΈΠ΄Π½ΠΎ, ΡΡΠΎ ΠΌΠΎΠΆΠ΅Ρ ΡΡ ΡΠ΄ΡΠΈΡΡ ΠΎΠ±ΡΠΈΠ΅ Ρ Π°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊΠΈ ΡΡΠ½ΠΊΡΠΈΠΎΠ½ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΠΈΠΏΠ°, ΡΠ°ΠΊ ΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΡΠΊΠ°Π·Π°Π½Π½ΡΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ Ρ ΠΎΡΡΠΎΡΠΎΠΆΠ½ΠΎΡΡΡΡ.
ΠΡΠ°ΠΊ, ΠΌΡ Ρ Π²Π°ΠΌΠΈ ΠΎΠ±ΡΡΠ΄ΠΈΠ»ΠΈ ΡΠ΅Π»ΡΠΉ ΡΡΠ΄ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΠΎΠ² ΠΊ ΡΠ΅ΡΠ΅Π½ΠΈΡ Π²ΠΎΠΏΡΠΎΡΠ° ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ ΠΎΠ±ΡΠΈΠΌ Π±Π»ΠΎΠΊΠ°ΠΌ Π΄Π°Π½Π½ΡΡ . ΠΡΠ΄ΡΡΠ΅ ΡΠ²Π΅ΡΠ΅Π½Ρ, Π² ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π΅ ΠΈΠΌΠ΅Π½ System.Threading Π΅ΡΡΡ ΠΈ Π΄ΡΡΠ³ΠΈΠ΅ ΡΠΈΠΏΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Ρ Π½Π°ΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΡ Π²Π°ΠΌ ΠΏΠΎΡΡΠ΅ΠΏΠ΅Π½Π½ΠΎ ΠΈΡΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΡ. Π Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠ΅ ΡΡΠΎΠΉ Π³Π»Π°Π²Ρ, ΠΏΠΎΡΠ²ΡΡΠ΅Π½Π½ΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ², Π΄Π°Π²Π°ΠΉΡΠ΅ ΡΠ°ΡΡΠΌΠΎΡΡΠΈΠΌ ΡΡΠΈ: Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΡΠΈΠΏΠ°: TimerCallback, Timer ΠΈ ThreadPool.
ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠ°ΠΉΠΌΠ΅ΡΠΎΠ² ΠΎΠ±ΡΠ°ΡΠ½ΠΎΠ³ΠΎ Π²ΡΠ·ΠΎΠ²Π°
ΠΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΡ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΡ Π²ΡΠ·ΡΠ²Π°ΡΡ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ ΡΠ΅ΡΠ΅Π· ΡΠ΅Π³ΡΠ»ΡΡΠ½ΡΠ΅ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΊΠΈ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΡΡΠ΅Π±ΠΎΠ²Π°ΡΡΡΡ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΡΠ΅ΠΊΡΡΠ΅Π³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Π² ΡΡΡΠΎΠΊΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠΉ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°ΡΠ΅Π»ΡΠ½ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ. Π Π΄ΡΡΠ³ΠΎΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡΡ ΠΏΠ΅ΡΠΈΠΎΠ΄ΠΈΡΠ΅ΡΠΊΠΈΠΉ Π²ΡΠ·ΠΎΠ² Π²ΡΠΏΠΎΠΌΠΎΠ³Π°ΡΠ΅Π»ΡΠ½ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ, Π²ΡΠΏΠΎΠ»Π½ΡΡΡΠ΅ΠΉ Π² ΡΠΎΠ½ΠΎΠ²ΠΎΠΌ ΡΠ΅ΠΆΠΈΠΌΠ΅ ΠΊΠ°ΠΊΠΈΠ΅-ΡΠΎ Π½Π΅ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π·Π°Π΄Π°ΡΠΈ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΡ ΠΏΠΎΡΡΡΠΏΠ»Π΅Π½ΠΈΡ Π½ΠΎΠ²ΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΡΠ»Π΅ΠΊΡΡΠΎΠ½Π½ΠΎΠΉ ΠΏΠΎΡΡΡ. ΠΠ»Ρ ΡΠ°ΠΊΠΈΡ ΡΠΈΡΡΠ°ΡΠΈΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΈΠΏ System. Threading.Timer Π² ΡΠΎΠ²ΠΎΠΊΡΠΏΠ½ΠΎΡΡΠΈ Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΌ Π΄Π΅Π»Π΅Π³Π°ΡΠΎΠΌ TimerCallback.
ΠΠ»Ρ ΠΏΡΠΈΠΌΠ΅ΡΠ° ΠΏΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, ΡΡΠΎ Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΠΊΠΎΠ½ΡΠΎΠ»ΡΠ½ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π΅ΠΆΠ΅ΡΠ΅ΠΊΡΠ½Π΄Π½ΠΎ Π²ΡΠ²ΠΎΠ΄ΠΈΡ ΡΠ΅ΠΊΡΡΠ΅Π΅ Π²ΡΠ΅ΠΌΡ, ΠΏΠΎΠΊΠ° ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π½Π΅ Π½Π°ΠΆΠΌΠ΅Ρ ΠΊΠ»Π°Π²ΠΈΡΡ, Π·Π°Π²Π΅ΡΡΠ°ΡΡΡΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΡΡΠΎΠ³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΠ΅ΡΠ²ΡΠΌ ΠΎΡΠ΅Π²ΠΈΠ΄Π½ΡΠΌ ΡΠ°Π³ΠΎΠΌ Π·Π΄Π΅ΡΡ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΌΠ΅ΡΠΎΠ΄Π°, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ Π²ΡΠ·ΡΠ²Π°ΡΡΡΡ ΡΠΈΠΏΠΎΠΌ Timer.
class TimePrinter {
static void PrintTime(object state) {
Console.WriteLine("ΠΡΠ΅ΠΌΡ: {0}", DateTime.Now.ToLongTimeString());
}
}
ΠΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄ ΠΈΠΌΠ΅Π΅Ρ ΠΎΠ΄ΠΈΠ½ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ ΡΠΈΠΏΠ° System.Object ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ void. Π’Π°ΠΊΠ°Ρ ΡΡΡΡΠΊΡΡΡΠ° ΠΌΠ΅ΡΠΎΠ΄Π° ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π΄Π΅Π»Π΅Π³Π°Ρ TimerCallback ΠΌΠΎΠΆΠ΅Ρ Π²ΡΠ·ΡΠ²Π°ΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ°ΠΊΠΈΠ΅ ΠΌΠ΅ΡΠΎΠ΄Ρ. ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅, ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°Π΅ΠΌΠΎΠ΅ ΡΠ΅Π»Π΅Π²ΠΎΠΌΡ ΠΌΠ΅ΡΠΎΠ΄Ρ Π΄Π΅Π»Π΅Π³Π°ΡΠ° TimerCallback, ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΡΡ Π»ΡΠ±ΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ (ΡΠ°ΠΊ, Π² ΡΠ»ΡΡΠ°Π΅ ΡΠ»Π΅ΠΊΡΡΠΎΠ½Π½ΠΎΠΉ ΠΏΠΎΡΡΡ ΡΡΠΎ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΈΠΌΡ ΡΠ΅ΡΠ²Π΅ΡΠ° Microsoft Exchange, Ρ ΠΊΠΎΡΠΎΡΡΠΌ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Π² Ρ ΠΎΠ΄Π΅ ΠΏΡΠΎΡΠ΅ΡΡΠ°). Π ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΈΠΏΠΎΠΌ System.Object, Π² Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ Π»ΡΠ±ΠΎΠ΅ ΡΠΈΡΠ»ΠΎ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ², Π΅ΡΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ System.Array ΠΈΠ»ΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠΉ ΠΊΠ»Π°ΡΡ (ΡΡΡΡΠΊΡΡΡΡ).