本文整理汇总了C#中System.Threading.Tasks.TaskScheduler类的典型用法代码示例。如果您正苦于以下问题:C# TaskScheduler类的具体用法?C# TaskScheduler怎么用?C# TaskScheduler使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
TaskScheduler类属于System.Threading.Tasks命名空间,在下文中一共展示了TaskScheduler类的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: Main
//引入命名空间
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
class Example
{
static void Main()
{
// Create a scheduler that uses two threads.
LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(2);
List<Task> tasks = new List<Task>();
// Create a TaskFactory and pass it our custom scheduler.
TaskFactory factory = new TaskFactory(lcts);
CancellationTokenSource cts = new CancellationTokenSource();
// Use our factory to run a set of tasks.
Object lockObj = new Object();
int outputItem = 0;
for (int tCtr = 0; tCtr <= 4; tCtr++) {
int iteration = tCtr;
Task t = factory.StartNew(() => {
for (int i = 0; i < 1000; i++) {
lock (lockObj) {
Console.Write("{0} in task t-{1} on thread {2} ",
i, iteration, Thread.CurrentThread.ManagedThreadId);
outputItem++;
if (outputItem % 3 == 0)
Console.WriteLine();
}
}
}, cts.Token);
tasks.Add(t);
}
// Use it to run a second set of tasks.
for (int tCtr = 0; tCtr <= 4; tCtr++) {
int iteration = tCtr;
Task t1 = factory.StartNew(() => {
for (int outer = 0; outer <= 10; outer++) {
for (int i = 0x21; i <= 0x7E; i++) {
lock (lockObj) {
Console.Write("'{0}' in task t1-{1} on thread {2} ",
Convert.ToChar(i), iteration, Thread.CurrentThread.ManagedThreadId);
outputItem++;
if (outputItem % 3 == 0)
Console.WriteLine();
}
}
}
}, cts.Token);
tasks.Add(t1);
}
// Wait for the tasks to complete before displaying a completion message.
Task.WaitAll(tasks.ToArray());
cts.Dispose();
Console.WriteLine("\n\nSuccessful completion.");
}
}
// Provides a task scheduler that ensures a maximum concurrency level while
// running on top of the thread pool.
public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
{
// Indicates whether the current thread is processing work items.
[ThreadStatic]
private static bool _currentThreadIsProcessingItems;
// The list of tasks to be executed
private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); // protected by lock(_tasks)
// The maximum concurrency level allowed by this scheduler.
private readonly int _maxDegreeOfParallelism;
// Indicates whether the scheduler is currently processing work items.
private int _delegatesQueuedOrRunning = 0;
// Creates a new instance with the specified degree of parallelism.
public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism)
{
if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
_maxDegreeOfParallelism = maxDegreeOfParallelism;
}
// Queues a task to the scheduler.
protected sealed override void QueueTask(Task task)
{
// Add the task to the list of tasks to be processed. If there aren't enough
// delegates currently queued or running to process tasks, schedule another.
lock (_tasks)
{
_tasks.AddLast(task);
if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism)
{
++_delegatesQueuedOrRunning;
NotifyThreadPoolOfPendingWork();
}
}
}
// Inform the ThreadPool that there's work to be executed for this scheduler.
private void NotifyThreadPoolOfPendingWork()
{
ThreadPool.UnsafeQueueUserWorkItem(_ =>
{
// Note that the current thread is now processing work items.
// This is necessary to enable inlining of tasks into this thread.
_currentThreadIsProcessingItems = true;
try
{
// Process all available items in the queue.
while (true)
{
Task item;
lock (_tasks)
{
// When there are no more items to be processed,
// note that we're done processing, and get out.
if (_tasks.Count == 0)
{
--_delegatesQueuedOrRunning;
break;
}
// Get the next item from the queue
item = _tasks.First.Value;
_tasks.RemoveFirst();
}
// Execute the task we pulled out of the queue
base.TryExecuteTask(item);
}
}
// We're done processing items on the current thread
finally { _currentThreadIsProcessingItems = false; }
}, null);
}
// Attempts to execute the specified task on the current thread.
protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
// If this thread isn't already processing a task, we don't support inlining
if (!_currentThreadIsProcessingItems) return false;
// If the task was previously queued, remove it from the queue
if (taskWasPreviouslyQueued)
// Try to run the task.
if (TryDequeue(task))
return base.TryExecuteTask(task);
else
return false;
else
return base.TryExecuteTask(task);
}
// Attempt to remove a previously scheduled task from the scheduler.
protected sealed override bool TryDequeue(Task task)
{
lock (_tasks) return _tasks.Remove(task);
}
// Gets the maximum concurrency level supported by this scheduler.
public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } }
// Gets an enumerable of the tasks currently scheduled on this scheduler.
protected sealed override IEnumerable<Task> GetScheduledTasks()
{
bool lockTaken = false;
try
{
Monitor.TryEnter(_tasks, ref lockTaken);
if (lockTaken) return _tasks;
else throw new NotSupportedException();
}
finally
{
if (lockTaken) Monitor.Exit(_tasks);
}
}
}
// The following is a portion of the output from a single run of the example:
// 'T' in task t1-4 on thread 3 'U' in task t1-4 on thread 3 'V' in task t1-4 on thread 3
// 'W' in task t1-4 on thread 3 'X' in task t1-4 on thread 3 'Y' in task t1-4 on thread 3
// 'Z' in task t1-4 on thread 3 '[' in task t1-4 on thread 3 '\' in task t1-4 on thread 3
// ']' in task t1-4 on thread 3 '^' in task t1-4 on thread 3 '_' in task t1-4 on thread 3
// '`' in task t1-4 on thread 3 'a' in task t1-4 on thread 3 'b' in task t1-4 on thread 3
// 'c' in task t1-4 on thread 3 'd' in task t1-4 on thread 3 'e' in task t1-4 on thread 3
// 'f' in task t1-4 on thread 3 'g' in task t1-4 on thread 3 'h' in task t1-4 on thread 3
// 'i' in task t1-4 on thread 3 'j' in task t1-4 on thread 3 'k' in task t1-4 on thread 3
// 'l' in task t1-4 on thread 3 'm' in task t1-4 on thread 3 'n' in task t1-4 on thread 3
// 'o' in task t1-4 on thread 3 'p' in task t1-4 on thread 3 ']' in task t1-2 on thread 4
// '^' in task t1-2 on thread 4 '_' in task t1-2 on thread 4 '`' in task t1-2 on thread 4
// 'a' in task t1-2 on thread 4 'b' in task t1-2 on thread 4 'c' in task t1-2 on thread 4
// 'd' in task t1-2 on thread 4 'e' in task t1-2 on thread 4 'f' in task t1-2 on thread 4
// 'g' in task t1-2 on thread 4 'h' in task t1-2 on thread 4 'i' in task t1-2 on thread 4
// 'j' in task t1-2 on thread 4 'k' in task t1-2 on thread 4 'l' in task t1-2 on thread 4
// 'm' in task t1-2 on thread 4 'n' in task t1-2 on thread 4 'o' in task t1-2 on thread 4
// 'p' in task t1-2 on thread 4 'q' in task t1-2 on thread 4 'r' in task t1-2 on thread 4
// 's' in task t1-2 on thread 4 't' in task t1-2 on thread 4 'u' in task t1-2 on thread 4
// 'v' in task t1-2 on thread 4 'w' in task t1-2 on thread 4 'x' in task t1-2 on thread 4
// 'y' in task t1-2 on thread 4 'z' in task t1-2 on thread 4 '{' in task t1-2 on thread 4
// '|' in task t1-2 on thread 4 '}' in task t1-2 on thread 4 '~' in task t1-2 on thread 4
// 'q' in task t1-4 on thread 3 'r' in task t1-4 on thread 3 's' in task t1-4 on thread 3
// 't' in task t1-4 on thread 3 'u' in task t1-4 on thread 3 'v' in task t1-4 on thread 3
// 'w' in task t1-4 on thread 3 'x' in task t1-4 on thread 3 'y' in task t1-4 on thread 3
// 'z' in task t1-4 on thread 3 '{' in task t1-4 on thread 3 '|' in task t1-4 on thread 3
示例2: MainWindow
//引入命名空间
using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace WPF_CS1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private int fileCount;
int colCount;
int rowCount;
private int tilePixelHeight;
private int tilePixelWidth;
private int largeImagePixelHeight;
private int largeImagePixelWidth;
private int largeImageStride;
PixelFormat format;
BitmapPalette palette = null;
public MainWindow()
{
InitializeComponent();
// For this example, values are hard-coded to a mosaic of 8x8 tiles.
// Each tile is 50 pixels high and 66 pixels wide and 32 bits per pixel.
colCount = 12;
rowCount = 8;
tilePixelHeight = 50;
tilePixelWidth = 66;
largeImagePixelHeight = tilePixelHeight * rowCount;
largeImagePixelWidth = tilePixelWidth * colCount;
largeImageStride = largeImagePixelWidth * (32 / 8);
this.Width = largeImagePixelWidth + 40;
image.Width = largeImagePixelWidth;
image.Height = largeImagePixelHeight;
}
private void button_Click(object sender, RoutedEventArgs e)
{
// For best results use 1024 x 768 jpg files at 32bpp.
string[] files = System.IO.Directory.GetFiles(@"C:\Users\Public\Pictures\Sample Pictures\", "*.jpg");
fileCount = files.Length;
Task<byte[]>[] images = new Task<byte[]>[fileCount];
for (int i = 0; i < fileCount; i++)
{
int x = i;
images[x] = Task.Factory.StartNew(() => LoadImage(files[x]));
}
// When they've all been loaded, tile them into a single byte array.
var tiledImage = Task.Factory.ContinueWhenAll(
images, (i) => TileImages(i));
// We are currently on the UI thread. Save the sync context and pass it to
// the next task so that it can access the UI control "image".
var UISyncContext = TaskScheduler.FromCurrentSynchronizationContext();
// On the UI thread, put the bytes into a bitmap and
// display it in the Image control.
var t3 = tiledImage.ContinueWith((antecedent) =>
{
// Get System DPI.
Matrix m = PresentationSource.FromVisual(Application.Current.MainWindow)
.CompositionTarget.TransformToDevice;
double dpiX = m.M11;
double dpiY = m.M22;
BitmapSource bms = BitmapSource.Create(largeImagePixelWidth,
largeImagePixelHeight,
dpiX,
dpiY,
format,
palette, //use default palette
antecedent.Result,
largeImageStride);
image.Source = bms;
}, UISyncContext);
}
byte[] LoadImage(string filename)
{
// Use the WPF BitmapImage class to load and
// resize the bitmap. NOTE: Only 32bpp formats are supported correctly.
// Support for additional color formats is left as an exercise
// for the reader. For more information, see documentation for ColorConvertedBitmap.
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.UriSource = new Uri(filename);
bitmapImage.DecodePixelHeight = tilePixelHeight;
bitmapImage.DecodePixelWidth = tilePixelWidth;
bitmapImage.EndInit();
format = bitmapImage.Format;
int size = (int)(bitmapImage.Height * bitmapImage.Width);
int stride = (int)bitmapImage.Width * 4;
byte[] dest = new byte[stride * tilePixelHeight];
bitmapImage.CopyPixels(dest, stride, 0);
return dest;
}
int Stride(int pixelWidth, int bitsPerPixel)
{
return (((pixelWidth * bitsPerPixel + 31) / 32) * 4);
}
// Map the individual image tiles to the large image
// in parallel. Any kind of raw image manipulation can be
// done here because we are not attempting to access any
// WPF controls from multiple threads.
byte[] TileImages(Task<byte[]>[] sourceImages)
{
byte[] largeImage = new byte[largeImagePixelHeight * largeImageStride];
int tileImageStride = tilePixelWidth * 4; // hard coded to 32bpp
Random rand = new Random();
Parallel.For(0, rowCount * colCount, (i) =>
{
// Pick one of the images at random for this tile.
int cur = rand.Next(0, sourceImages.Length);
byte[] pixels = sourceImages[cur].Result;
// Get the starting index for this tile.
int row = i / colCount;
int col = (int)(i % colCount);
int idx = ((row * (largeImageStride * tilePixelHeight)) + (col * tileImageStride));
// Write the pixels for the current tile. The pixels are not contiguous
// in the array, therefore we have to advance the index by the image stride
// (minus the stride of the tile) for each scanline of the tile.
int tileImageIndex = 0;
for (int j = 0; j < tilePixelHeight; j++)
{
// Write the next scanline for this tile.
for (int k = 0; k < tileImageStride; k++)
{
largeImage[idx++] = pixels[tileImageIndex++];
}
// Advance to the beginning of the next scanline.
idx += largeImageStride - tileImageStride;
}
});
return largeImage;
}
}
}