После выполнения программы порядок следования элементов в результирующей последовательности будет отражать порядок их расположения в исходной последовательности.
Отмена параллельного запроса
Параллельный запрос отменяется таким же образом, как и задача. И в том и в другом случае отмена опирается на структуруCancellationToken,получаемую из классаCancellationTokenSource.Получаемый в итоге признак отмены передается запросу с помощью методаWithCancellation . Отмена параллельного запроса производится методомCancel , который вызывается для источника признаков отмены. Главное отличие отмены параллельного запроса от отмены задачи состоит в следующем: когда параллельный запрос отменяется, он генерирует исключениеOperationCanceledException,а неAggregateException.Но в тех случаях, когда запрос способен сгенерировать несколько исключений, исключениеOperationCanceledExceptionможет быть объединено в совокупное исключениеAggregateException.Поэтому отслеживать лучше оба вида исключений.
Ниже приведена форма объявления методаWithCancellation:
public static ParallelQuery
WithCancellation
this ParallelQuery
CancellationToken
где
В приведенном ниже примере программы демонстрируется порядок отмены параллельного запроса, сформированного в программе из предыдущего примера. В данной программе организуется отдельная задача, которая ожидает в течение 100 миллисекунд, а затем отменяет запрос. Отдельная задача требуется потому, что циклforeach,в котором выполняется запрос, блокирует выполнение методаMain до завершения цикла.
using System.Linq; using System.Threading; using System.Threading.Tasks;
class PLINQCancelDemo {
static void Main {
CancellationTokenSource cancelTokSrc = new CancellationTokenSource; int[] data = new int[10000000];
// Инициализировать массив данных положительными значениями, for (int i=0; i < data.Length; i++) data[i] = i;
//А теперь ввести в массив данных ряд отрицательных значений, data[1000] = -1; data [14000] = -2; data[15000] = -3;
data[676000] = -4; ч
data[8024540] = -5; data [9908000] = -6;
// Использовать запрос PLINQ для поиска отрицательных значений, var negatives = from val in data.AsParallel.
WithCancellation(cancelTokSrc.Token) where val < 0 select val;
// Создать задачу для отмены запроса по истечении 100 миллисекунд.
Task cancelTsk = Task.Factory.StartNew( => {
Thread.Sleep(100); • cancelTokSrc.Cancel;
});
try {