Interlocked.Decrement Methode
Definitie
Belangrijk
Bepaalde informatie heeft betrekking op een voorlopige productversie die aanzienlijk kan worden gewijzigd voordat deze wordt uitgebracht. Microsoft biedt geen enkele expliciete of impliciete garanties met betrekking tot de informatie die hier wordt verstrekt.
Hiermee wordt een opgegeven variabele afgekoppeld en wordt het resultaat opgeslagen als een atomische bewerking.
Overloads
| Name | Description |
|---|---|
| Decrement(Int32) |
Hiermee wordt een opgegeven variabele afgekoppeld en wordt het resultaat opgeslagen als een atomische bewerking. |
| Decrement(Int64) |
Hiermee wordt de opgegeven variabele ongedaan gemaakt en wordt het resultaat opgeslagen als een atomische bewerking. |
Decrement(Int32)
Hiermee wordt een opgegeven variabele afgekoppeld en wordt het resultaat opgeslagen als een atomische bewerking.
public:
static int Decrement(int % location);
public static int Decrement(ref int location);
static member Decrement : int -> int
Public Shared Function Decrement (ByRef location As Integer) As Integer
Parameters
- location
- Int32
De variabele waarvan de waarde moet worden afgebroken.
Retouren
De waarde van de variabele direct nadat de bewerking is afgebroken.
Uitzonderingen
Het adres van location is een null aanwijzer.
Het adres van location is een null aanwijzer.
Voorbeelden
In het volgende voorbeeld wordt bepaald hoeveel willekeurige getallen tussen 0 en 1.000 zijn vereist om 1000 willekeurige getallen met een middelpuntwaarde te genereren. Als u het aantal middelpuntwaarden, een variabele, wilt bijhouden, midpointCountwordt deze ingesteld op 1000 en afgebroken telkens wanneer de generator voor willekeurige getallen een middelpuntwaarde retourneert. Omdat drie threads de willekeurige getallen genereren, wordt de Decrement(Int32) methode aangeroepen om ervoor te zorgen dat meerdere threads niet gelijktijdig worden bijgewerkt midpointCount . Houd er rekening mee dat er ook een vergrendeling wordt gebruikt om de generator voor willekeurige getallen te beveiligen en dat een CountdownEvent object wordt gebruikt om ervoor te zorgen dat de Main methode de uitvoering niet voor de drie threads voltooit.
using System;
using System.Threading;
public class Example
{
const int LOWERBOUND = 0;
const int UPPERBOUND = 1001;
static Object lockObj = new Object();
static Random rnd = new Random();
static CountdownEvent cte;
static int totalCount = 0;
static int totalMidpoint = 0;
static int midpointCount = 10000;
public static void Main()
{
cte = new CountdownEvent(1);
// Start three threads.
for (int ctr = 0; ctr <= 2; ctr++) {
cte.AddCount();
Thread th = new Thread(GenerateNumbers);
th.Name = "Thread" + ctr.ToString();
th.Start();
}
cte.Signal();
cte.Wait();
Console.WriteLine();
Console.WriteLine("Total midpoint values: {0,10:N0} ({1:P3})",
totalMidpoint, totalMidpoint/((double)totalCount));
Console.WriteLine("Total number of values: {0,10:N0}",
totalCount);
}
private static void GenerateNumbers()
{
int midpoint = (UPPERBOUND - LOWERBOUND) / 2;
int value = 0;
int total = 0;
int midpt = 0;
do {
lock (lockObj) {
value = rnd.Next(LOWERBOUND, UPPERBOUND);
}
if (value == midpoint) {
Interlocked.Decrement(ref midpointCount);
midpt++;
}
total++;
} while (Volatile.Read(ref midpointCount) > 0);
Interlocked.Add(ref totalCount, total);
Interlocked.Add(ref totalMidpoint, midpt);
string s = String.Format("Thread {0}:\n", Thread.CurrentThread.Name) +
String.Format(" Random Numbers: {0:N0}\n", total) +
String.Format(" Midpoint values: {0:N0} ({1:P3})", midpt,
((double) midpt)/total);
Console.WriteLine(s);
cte.Signal();
}
}
// The example displays output like the following:
// Thread Thread2:
// Random Numbers: 3,204,021
// Midpoint values: 3,156 (0.099 %)
// Thread Thread0:
// Random Numbers: 4,073,592
// Midpoint values: 4,015 (0.099 %)
// Thread Thread1:
// Random Numbers: 2,828,192
// Midpoint values: 2,829 (0.100 %)
//
// Total midpoint values: 10,000 (0.099 %)
// Total number of values: 10,105,805
Imports System.Threading
Module Example
Const LOWERBOUND As Integer = 0
Const UPPERBOUND As Integer = 1001
Dim lockObj As New Object()
Dim rnd As New Random()
Dim cte As CountdownEvent
Dim totalCount As Integer = 0
Dim totalMidpoint As Integer = 0
Dim midpointCount As Integer = 10000
Public Sub Main()
cte = New CountdownEvent(1)
' Start three threads.
For ctr As Integer = 0 To 2
cte.AddCount()
Dim th As New Thread(AddressOf GenerateNumbers)
th.Name = "Thread" + ctr.ToString()
th.Start()
Next
cte.Signal()
cte.Wait()
Console.WriteLine()
Console.WriteLine("Total midpoint values: {0,10:N0} ({1:P3})",
totalMidpoint, totalMidpoint/totalCount)
Console.WriteLine("Total number of values: {0,10:N0}",
totalCount)
End Sub
Private Sub GenerateNumbers()
Dim midpoint As Integer = (upperBound - lowerBound) \ 2
Dim value As Integer = 0
Dim total As Integer = 0
Dim midpt As Integer = 0
Do
SyncLock lockObj
value = rnd.Next(lowerBound, upperBound)
End SyncLock
If value = midpoint Then
Interlocked.Decrement(midpointCount)
midpt += 1
End If
total += 1
Loop While midpointCount > 0
Interlocked.Add(totalCount, total)
Interlocked.Add(totalMidpoint, midpt)
Dim s As String = String.Format("Thread {0}:", Thread.CurrentThread.Name) + vbCrLf +
String.Format(" Random Numbers: {0:N0}", total) + vbCrLf +
String.Format(" Midpoint values: {0:N0} ({1:P3})", midpt, midpt/total)
Console.WriteLine(s)
cte.Signal()
End Sub
End Module
' The example displays output like the following:
' Thread Thread2:
' Random Numbers: 3,204,021
' Midpoint values: 3,156 (0.099 %)
' Thread Thread0:
' Random Numbers: 4,073,592
' Midpoint values: 4,015 (0.099 %)
' Thread Thread1:
' Random Numbers: 2,828,192
' Midpoint values: 2,829 (0.100 %)
'
' Total midpoint values: 10,000 (0.099 %)
' Total number of values: 10,105,805
Het volgende voorbeeld is vergelijkbaar met de vorige, behalve dat de Task klasse wordt gebruikt in plaats van een threadprocedure om 50.000 willekeurige gehele punten te genereren. In dit voorbeeld vervangt een lambda-expressie de GenerateNumbers threadprocedure en elimineert de aanroep naar de Task.WaitAll methode de noodzaak voor het CountdownEvent object.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
public class Example
{
const int LOWERBOUND = 0;
const int UPPERBOUND = 1001;
static Object lockObj = new Object();
static Random rnd = new Random();
static int totalCount = 0;
static int totalMidpoint = 0;
static int midpointCount = 50000;
public static async Task Main()
{
List<Task> tasks = new List<Task>();
// Start three tasks.
for (int ctr = 0; ctr <= 2; ctr++)
tasks.Add(Task.Run( () => { int midpoint = (UPPERBOUND - LOWERBOUND) / 2;
int value = 0;
int total = 0;
int midpt = 0;
do {
lock (lockObj) {
value = rnd.Next(LOWERBOUND, UPPERBOUND);
}
if (value == midpoint) {
Interlocked.Decrement(ref midpointCount);
midpt++;
}
total++;
} while (Volatile.Read(ref midpointCount) > 0);
Interlocked.Add(ref totalCount, total);
Interlocked.Add(ref totalMidpoint, midpt);
string s = String.Format("Task {0}:\n", Task.CurrentId) +
String.Format(" Random Numbers: {0:N0}\n", total) +
String.Format(" Midpoint values: {0:N0} ({1:P3})", midpt,
((double) midpt)/total);
Console.WriteLine(s);
} ));
await Task.WhenAll(tasks.ToArray());
Console.WriteLine();
Console.WriteLine("Total midpoint values: {0,10:N0} ({1:P3})",
totalMidpoint, totalMidpoint/((double)totalCount));
Console.WriteLine("Total number of values: {0,10:N0}",
totalCount);
}
}
// The example displays output like the following:
// Task 1:
// Random Numbers: 24,530,624
// Midpoint values: 24,675 (0.101 %)
// Task 2:
// Random Numbers: 7,079,718
// Midpoint values: 7,093 (0.100 %)
// Task 3:
// Random Numbers: 18,284,617
// Midpoint values: 18,232 (0.100 %)
//
// Total midpoint values: 50,000 (0.100 %)
// Total number of values: 49,894,959
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks
Module Example
Const LOWERBOUND As Integer = 0
Const UPPERBOUND As Integer = 1001
Dim lockObj As New Object()
Dim rnd As New Random()
Dim totalCount As Integer = 0
Dim totalMidpoint As Integer = 0
Dim midpointCount As Integer = 50000
Public Sub Main()
Dim tasks As New List(Of Task)()
' Start three tasks.
For ctr As Integer = 0 To 2
tasks.Add( Task.Run(Sub()
Dim midpoint As Integer = (upperBound - lowerBound) \ 2
Dim value As Integer = 0
Dim total As Integer = 0
Dim midpt As Integer = 0
Do
SyncLock lockObj
value = rnd.Next(lowerBound, upperBound)
End SyncLock
If value = midpoint Then
Interlocked.Decrement(midpointCount)
midpt += 1
End If
total += 1
Loop While midpointCount > 0
Interlocked.Add(totalCount, total)
Interlocked.Add(totalMidpoint, midpt)
Dim s As String = String.Format("Task {0}:", Task.CurrentId) + vbCrLf +
String.Format(" Random Numbers: {0:N0}", total) + vbCrLf +
String.Format(" Midpoint values: {0:N0} ({1:P3})", midpt, midpt/total)
Console.WriteLine(s)
End Sub ))
Next
Task.WaitAll(tasks.ToArray())
Console.WriteLine()
Console.WriteLine("Total midpoint values: {0,10:N0} ({1:P3})",
totalMidpoint, totalMidpoint/totalCount)
Console.WriteLine("Total number of values: {0,10:N0}",
totalCount)
End Sub
End Module
' The example displays output like the following:
' Task 1:
' Random Numbers: 24,530,624
' Midpoint values: 24,675 (0.101 %)
' Task 2:
' Random Numbers: 7,079,718
' Midpoint values: 7,093 (0.100 %)
' Task 3:
' Random Numbers: 18,284,617
' Midpoint values: 18,232 (0.100 %)
'
' Total midpoint values: 50,000 (0.100 %)
' Total number of values: 49,894,959
Opmerkingen
Met deze methode wordt een overloopvoorwaarde verwerkt door te verpakken: If location = Int32.MinValue, location - 1 = . Int32.MaxValue Er wordt geen uitzondering opgeworpen.
Zie ook
- Het Beheerd Draadbeheer
- Overzicht van synchronisatie primitiefen
Van toepassing op
Decrement(Int64)
Hiermee wordt de opgegeven variabele ongedaan gemaakt en wordt het resultaat opgeslagen als een atomische bewerking.
public:
static long Decrement(long % location);
public static long Decrement(ref long location);
static member Decrement : int64 -> int64
Public Shared Function Decrement (ByRef location As Long) As Long
Parameters
- location
- Int64
De variabele waarvan de waarde moet worden afgebroken.
Retouren
De waarde van de variabele direct nadat de bewerking is afgebroken.
Uitzonderingen
Het adres van location is een null aanwijzer.
Het adres van location is een null aanwijzer.
Opmerkingen
Met deze methode wordt een overloopvoorwaarde verwerkt door te verpakken: als location = Int64.MinValue, location - 1 = . Int64.MaxValue Er wordt geen uitzondering opgeworpen.
Zie ook
- Increment
- Add
- Read(Int64)
- Het Beheerd Draadbeheer
- Overzicht van synchronisatie primitiefen