Interlocked.Decrement Метод
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Уменьшает значение заданной переменной и сохраняет результат в виде атомарной операции.
Перегрузки
| Имя | Описание |
|---|---|
| Decrement(Int64) |
Уменьшает значение заданной переменной и сохраняет результат — как атомарная операция. |
| Decrement(Int32) |
Уменьшает значение заданной переменной и сохраняет результат в виде атомарной операции. |
| Decrement(UInt32) |
Уменьшает значение заданной переменной и сохраняет результат в виде атомарной операции. |
| Decrement(UInt64) |
Уменьшает значение заданной переменной и сохраняет результат в виде атомарной операции. |
Decrement(Int64)
- Исходный код:
- Interlocked.CoreCLR.cs
- Исходный код:
- Interlocked.CoreCLR.cs
- Исходный код:
- Interlocked.CoreCLR.cs
- Исходный код:
- Interlocked.CoreCLR.cs
Уменьшает значение заданной переменной и сохраняет результат — как атомарная операция.
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
Параметры
- location
- Int64
Переменная, у которой уменьшается значение.
Возвращаемое значение
Значение переменной сразу после завершения операции уменьшения.
Исключения
Адрес location является указателем null.
Адрес location является указателем null.
Комментарии
Этот метод обрабатывает условие переполнения путем упаковки: если location = Int64.MinValue, location - 1 = . Int64.MaxValue Исключение не выдается.
См. также раздел
Применяется к
Decrement(Int32)
- Исходный код:
- Interlocked.CoreCLR.cs
- Исходный код:
- Interlocked.CoreCLR.cs
- Исходный код:
- Interlocked.CoreCLR.cs
- Исходный код:
- Interlocked.CoreCLR.cs
Уменьшает значение заданной переменной и сохраняет результат в виде атомарной операции.
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
Параметры
- location
- Int32
Переменная, у которой уменьшается значение.
Возвращаемое значение
Значение переменной сразу после завершения операции уменьшения.
Исключения
Адрес location является указателем null.
Адрес location является указателем null.
Примеры
В следующем примере определяется, сколько случайных чисел в диапазоне от 0 до 1000 требуется для создания 1000 случайных чисел со значением в середине. Чтобы отслеживать количество значений середины, переменная , задается равным 1000 и уменьшается каждый раз, midpointCountкогда генератор случайных чисел возвращает значение средней точки. Так как три потока создают случайные числа, Decrement(Int32) вызывается метод , чтобы гарантировать, что несколько потоков не обновляются midpointCount одновременно. Обратите внимание, что блокировка также используется для защиты генератора случайных чисел, а CountdownEvent объект используется для обеспечения того, чтобы Main метод не завершил выполнение до трех потоков.
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
Следующий пример аналогичен предыдущему, за исключением того, что он использует Task класс вместо процедуры потока для создания 50 000 случайных целых чисел в середине. В этом примере лямбда-выражение заменяет процедуру GenerateNumbers потока, а вызов Task.WaitAll метода устраняет необходимость в объекте CountdownEvent .
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
Комментарии
Этот метод обрабатывает условие переполнения путем упаковки: Если location = Int32.MinValue, location - 1 = . Int32.MaxValue Исключение не выдается.
См. также раздел
Применяется к
Decrement(UInt32)
- Исходный код:
- Interlocked.cs
- Исходный код:
- Interlocked.cs
- Исходный код:
- Interlocked.cs
- Исходный код:
- Interlocked.cs
Внимание
Этот API несовместим с CLS.
Уменьшает значение заданной переменной и сохраняет результат в виде атомарной операции.
public:
static System::UInt32 Decrement(System::UInt32 % location);
[System.CLSCompliant(false)]
public static uint Decrement(ref uint location);
[<System.CLSCompliant(false)>]
static member Decrement : uint32 -> uint32
Public Shared Function Decrement (ByRef location As UInteger) As UInteger
Параметры
- location
- UInt32
Переменная, у которой уменьшается значение.
Возвращаемое значение
Значение переменной сразу после завершения операции уменьшения.
- Атрибуты
Исключения
Адрес location является указателем null.
Применяется к
Decrement(UInt64)
- Исходный код:
- Interlocked.cs
- Исходный код:
- Interlocked.cs
- Исходный код:
- Interlocked.cs
- Исходный код:
- Interlocked.cs
Внимание
Этот API несовместим с CLS.
Уменьшает значение заданной переменной и сохраняет результат в виде атомарной операции.
public:
static System::UInt64 Decrement(System::UInt64 % location);
[System.CLSCompliant(false)]
public static ulong Decrement(ref ulong location);
[<System.CLSCompliant(false)>]
static member Decrement : uint64 -> uint64
Public Shared Function Decrement (ByRef location As ULong) As ULong
Параметры
- location
- UInt64
Переменная, у которой уменьшается значение.
Возвращаемое значение
Значение переменной сразу после завершения операции уменьшения.
- Атрибуты
Исключения
Адрес location является указателем null.