signed char
: -127 to 127 (note, not -128 to 127; this accommodates 1's-complement platforms)unsigned char
: 0 to 255- "plain"
char
: -127 to 127 or 0 to 255 (depends on default char signedness) signed short
: -32767 to 32767unsigned short
: 0 to 65535signed int
: -32767 to 32767unsigned int
: 0 to 65535signed long
: -2147483647 to 2147483647unsigned long
: 0 to 4294967295signed long long
: -9223372036854775807 to 9223372036854775807unsigned long long
: 0 to 18446744073709551615
пятница, 29 ноября 2013 г.
C++ Types
пятница, 15 ноября 2013 г.
Blocking Collection
http://msdn.microsoft.com/en-us/library/dd460684(v=vs.110).aspx
http://msdn.microsoft.com/ru-ru/library/dd460684(v=vs.110).aspx
How to: Use ForEach to Remove Items in a BlockingCollection
In addition to taking items from a BlockingCollection<T> by using the Take and TryTake method, you can also use a foreach (For Each in Visual Basic) to remove items until adding is completed and the collection is empty. This is called a mutating enumeration or consuming enumeration because, unlike a typical foreach(For Each) loop, this enumerator modifies the source collection by removing items.
The following example shows how to remove all the items in a BlockingCollection<T> by using a foreach (For Each) loop.
namespace EnumerateBlockingCollection
{
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
class Program
{
// Limit the collection size to 2000 items
// at any given time. Set itemsToProduce to >500
// to hit the limit.
const int upperLimit = 1000;
// Adjust this number to see how it impacts
// the producing-consuming pattern.
const int itemsToProduce = 100;
static BlockingCollection<long> collection = new BlockingCollection<long>(upperLimit);
// Variables for diagnostic output only.
static Stopwatch sw = new Stopwatch();
static int totalAdditions = 0;
// Counter for synchronizing producers.
static int producersStillRunning = 2;
static void Main(string[] args)
{
// Start the stopwatch.
sw.Start();
// Queue the Producer threads. Store in an array
// for use with ContinueWhenAll
Task[] producers = new Task[2];
producers[0] = Task.Run(() => RunProducer("A", 0));
producers[1] = Task.Run(() => RunProducer("B", itemsToProduce));
// Create a cleanup task that will call CompleteAdding after
// all producers are done adding items.
Task cleanup = Task.Factory.ContinueWhenAll(producers, (p) => collection.CompleteAdding());
// Queue the Consumer thread. Put this call
// before Parallel.Invoke to begin consuming as soon as
// the producers add items.
Task.Run(() => RunConsumer());
// Keep the console window open while the
// consumer thread completes its output.
Console.ReadKey();
}
static void RunProducer(string ID, int start)
{
int additions = 0;
for (int i = start; i < start + itemsToProduce; i++)
{
// The data that is added to the collection.
long ticks = sw.ElapsedTicks;
// Display additions and subtractions.
Console.WriteLine("{0} adding tick value {1}. item# {2}", ID, ticks, i);
if(!collection.IsAddingCompleted)
collection.Add(ticks);
// Counter for demonstration purposes only.
additions++;
// Uncomment this line to
// slow down the producer threads ing.
Thread.SpinWait(100000);
}
Interlocked.Add(ref totalAdditions, additions);
Console.WriteLine("{0} is done adding: {1} items", ID, additions);
}
static void RunConsumer()
{
// GetConsumingEnumerable returns the enumerator for the
// underlying collection.
int subtractions = 0;
foreach (var item in collection.GetConsumingEnumerable())
{
Console.WriteLine("Consuming tick value {0} : item# {1} : current count = {2}",
item.ToString("D18"), subtractions++, collection.Count);
}
Console.WriteLine("Total added: {0} Total consumed: {1} Current count: {2} ",
totalAdditions, subtractions, collection.Count());
sw.Stop();
Console.WriteLine("Press any key to exit");
}
}
}
This example uses a foreach loop with the BlockingCollection<T>.GetConsumingEnumerable method in the consuming thread, which causes each item to be removed from the collection as it is enumerated. System.Collections.Concurrent.BlockingCollection<T> limits the maximum number of items that are in the collection at any time. Enumerating the collection in this way blocks the consumer thread if no items are available or if the collection is empty. In this example blocking is not a concern because the producer thread adds items faster than they can be consumed.
There is no guarantee that the items are enumerated in the same order in which they are added by the producer threads.
To enumerate the collection without modifying it, just use foreach (For Each) without the GetConsumingEnumerable method. However, it is important to understand that this kind of enumeration represents a snapshot of the collection at a precise point in time. If other threads are adding or removing items concurrently while you are executing the loop, then the loop might not represent the actual state of the collection.
In addition to taking items from a BlockingCollection<T> by using the Take and TryTake method, you can also use a foreach (For Each in Visual Basic) to remove items until adding is completed and the collection is empty. This is called a mutating enumeration or consuming enumeration because, unlike a typical foreach(For Each) loop, this enumerator modifies the source collection by removing items.
The following example shows how to remove all the items in a BlockingCollection<T> by using a foreach (For Each) loop.
namespace EnumerateBlockingCollection { using System; using System.Collections.Concurrent; using System.Diagnostics; class Program { // Limit the collection size to 2000 items // at any given time. Set itemsToProduce to >500 // to hit the limit. const int upperLimit = 1000; // Adjust this number to see how it impacts // the producing-consuming pattern. const int itemsToProduce = 100; static BlockingCollection<long> collection = new BlockingCollection<long>(upperLimit); // Variables for diagnostic output only. static Stopwatch sw = new Stopwatch(); static int totalAdditions = 0; // Counter for synchronizing producers. static int producersStillRunning = 2; static void Main(string[] args) { // Start the stopwatch. sw.Start(); // Queue the Producer threads. Store in an array // for use with ContinueWhenAll Task[] producers = new Task[2]; producers[0] = Task.Run(() => RunProducer("A", 0)); producers[1] = Task.Run(() => RunProducer("B", itemsToProduce)); // Create a cleanup task that will call CompleteAdding after // all producers are done adding items. Task cleanup = Task.Factory.ContinueWhenAll(producers, (p) => collection.CompleteAdding()); // Queue the Consumer thread. Put this call // before Parallel.Invoke to begin consuming as soon as // the producers add items. Task.Run(() => RunConsumer()); // Keep the console window open while the // consumer thread completes its output. Console.ReadKey(); } static void RunProducer(string ID, int start) { int additions = 0; for (int i = start; i < start + itemsToProduce; i++) { // The data that is added to the collection. long ticks = sw.ElapsedTicks; // Display additions and subtractions. Console.WriteLine("{0} adding tick value {1}. item# {2}", ID, ticks, i); if(!collection.IsAddingCompleted) collection.Add(ticks); // Counter for demonstration purposes only. additions++; // Uncomment this line to // slow down the producer threads ing. Thread.SpinWait(100000); } Interlocked.Add(ref totalAdditions, additions); Console.WriteLine("{0} is done adding: {1} items", ID, additions); } static void RunConsumer() { // GetConsumingEnumerable returns the enumerator for the // underlying collection. int subtractions = 0; foreach (var item in collection.GetConsumingEnumerable()) { Console.WriteLine("Consuming tick value {0} : item# {1} : current count = {2}", item.ToString("D18"), subtractions++, collection.Count); } Console.WriteLine("Total added: {0} Total consumed: {1} Current count: {2} ", totalAdditions, subtractions, collection.Count()); sw.Stop(); Console.WriteLine("Press any key to exit"); } } }
This example uses a foreach loop with the BlockingCollection<T>.GetConsumingEnumerable method in the consuming thread, which causes each item to be removed from the collection as it is enumerated. System.Collections.Concurrent.BlockingCollection<T> limits the maximum number of items that are in the collection at any time. Enumerating the collection in this way blocks the consumer thread if no items are available or if the collection is empty. In this example blocking is not a concern because the producer thread adds items faster than they can be consumed.
There is no guarantee that the items are enumerated in the same order in which they are added by the producer threads.
To enumerate the collection without modifying it, just use foreach (For Each) without the GetConsumingEnumerable method. However, it is important to understand that this kind of enumeration represents a snapshot of the collection at a precise point in time. If other threads are adding or removing items concurrently while you are executing the loop, then the loop might not represent the actual state of the collection.
четверг, 7 ноября 2013 г.
Ticks in long to DateTime
http://stackoverflow.com/questions/1129410/format-from-ticks-to-date
DateTime date = new DateTime(long.Parse(logText));
Or
DateTime logDate = new DateTime(logText);
DateTime date = new DateTime(long.Parse(logText));
Or
DateTime logDate = new DateTime(logText);
вторник, 5 ноября 2013 г.
Task.Run - Method
http://msdn.microsoft.com/en-us/library/hh195051(v=vs.110).aspx
using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; public class Example { public static void Main() { var list = new ConcurrentBag<string>(); string[] dirNames = { ".", ".." }; List<Task> tasks = new List<Task>(); foreach (var dirName in dirNames) { Task t = Task.Run( () => { foreach(var path in Directory.GetFiles(dirName)) list.Add(path); } ); tasks.Add(t); } Task.WaitAll(tasks.ToArray()); foreach (Task t in tasks) Console.WriteLine("Task {0} Status: {1}", t.Id, t.Status); Console.WriteLine("Number of files read: {0}", list.Count); } } // The example displays output like the following: // Task 1 Status: RanToCompletion // Task 2 Status: RanToCompletion // Number of files read: 23
async, await
http://stackoverflow.com/questions/14455293/async-and-await
The following Windows Forms example illustrates the use of await in an async method, WaitAsynchronouslyAsync. Contrast the behavior of that method with the behavior of WaitSynchronously. Without an await operator applied to a task, WaitSynchronously runs synchronously despite the use of the async modifier in its definition and a call to Thread.Sleep in its body.
private async void button1_Click(object sender, EventArgs e)
{
// Call the method that runs asynchronously.
string result = await WaitAsynchronouslyAsync();
// Call the method that runs synchronously.
//string result = await WaitSynchronously ();
// Display the result.
textBox1.Text += result;
}
// The following method runs asynchronously. The UI thread is not
// blocked during the delay. You can move or resize the Form1 window
// while Task.Delay is running.
public async Task<string> WaitAsynchronouslyAsync()
{
await Task.Delay(10000);
return "Finished";
}
// The following method runs synchronously, despite the use of async.
// You cannot move or resize the Form1 window while Thread.Sleep
// is running because the UI thread is blocked.
public async Task<string> WaitSynchronously()
{
// Add a using directive for System.Threading.
Thread.Sleep(10000);
return "Finished";
}
async await
http://habrahabr.ru/post/162353/
12 декабря 2012 в 16:07Использование async и await в C# — лучшие практикиперевод tutorial
Ключевые слова async и await, введённые в C# 5.0, значительно упрощают асинхронное программирование. Они также скрывают за собой некоторые сложности, которые, если вы потеряете бдительность, могут добавить проблем в ваш код. Описанные ниже практики пригодятся вам, если вы создаёте асинхронный код для .NET приложений.
Используйте async /await только для тех мест, которые могут длиться «долго»
Здесь всё просто. Создание
Task
и других структур для управления асинхронными операциями добавляет некоторые накладные расходы. Если ваша операция действительно продолжительна, например выполнение IO запроса, тогда эти расходы в основном не будут заметны. А в том случае, если ваша операция коротка или займёт несколько циклов процессора, тогда возможно будет лучше выполнять эту операцию синхронно.В целом, команда, работавшая над .NET Framework, проделала неплохую работу по выбору функциональсти, которая должна быть асинхронной. Так, если метод фреймворка заканчивается на
Async
и возвращает задачу, тогда, скорее всего вы должны использовать его асинхронно.Предпочитайте async/await вместо Task
Написание асинхронного кода, используя
async/await
, намного упрощает и сам процесс создания кода, и его чтение, нежели использование задач Task
.public Task<Data> GetDataAsync()
{
return MyWebService.FetchDataAsync()
.ContinueWith(t => new Data (t.Result));
}
public async Task<Data> GetDataAsync()
{
var result = await MyWebService.FetchDataAsync();
return new Data (result);
}
В терминах производительности, оба метода, представленные выше, имеют небольшие накладные расходы, но они несколько по-разному масштабируются при увеличении количества задач в них:
Task
строит цепочку продолжений, которая увеличивается в соответствии с количеством задач, связанных последовательно, и состояние системы управляется через замыкания, найденные компилятором.Async/await
строит машину состояний, которая не использует дополнительных ресурсов при добавлении новых шагов. Однако компилятор может определить больше переменных для сохранение в стеки машины состояний, в зависимости от вашего кода (и компилятора). В статье на MSDN отлично расписаны детали происходящего.
В большинстве сценариев
async/await
будет использовать меньше ресурсов и выполняться быстрее, чем задачиTask
.Используйте уже выполненную пустую статическую задачу для условного кода
Иногда вы хотите запустить задачу только при каком-то условии. К сожалению,
await
вызоветNullReferenceException
, если получит null
вместо задачи, а обработка этого сделает ваш код менее читабельным.public async Task<Data> GetDataAsync(bool getLatestData)
{
Task<WebData> task = null;
if (getLatestData)
task = MyWebService.FetchDataAsync();
// здесь выполним другую работу
// и не забудем проверить на null
WebData result = null;
if (task != null)
result = await task;
return new Data (result);
}
Один из способов немного упростить код – использовать пустую задачу, которая уже выполнена. Полученный код будет чище:
public async Task<Data> GetDataAsync(bool getLatestData)
{
var task = getLatestData ? MyWebService.FetchDataAsync() : Empty<WebData>.Task;
// здесь выполним другую работу
// task всегда не null
return new Data (await task);
}
Убедитесь, что задача является статической и создана как завершённая. Например:
public static class Empty<T>
{
public static Task<T> Task { get { return _task; } }
private static readonly Task<T> _task = System.Threading.Tasks.Task.FromResult(default(T));
}
Производительность: предпочитайте кэшировать сами задачи, нежели их данные
Существую некоторые накладные расходы при создании задач. Если вы кэшируете ваши результаты, но потом конвертируете их обратно в задачи, вы, возможно, создаете дополнительные объекты задач.
public Task<byte[]> GetContentsOfUrl(string url)
{
byte[] bytes;
if (_cache.TryGetValue(url, out bytes))
// дополнительная задача создаётся здесь
return Task<byte[]>.Factory.StartNew(() => bytes);
bytes = MyWebService.GetContentsAsync(url)
.ContinueWith(t => { _cache.Add(url, t.Result); return t.Result; );
}
// это не потокобезоспасно (не копируйте себе этот код как есть)
private static Dictionary<string, byte[]> _cache = new Dictionary<string, byte[]>();
Вместо этого будет лучше копировать в кэш сами задачи. В этом случае использующий их код может ждать уже выполненную задачу. В Task Parallel Library присутствуют оптимизации для того, чтобы код ожидающий выполнения уже завершённой задачи выполнялся быстрее.
public Task<byte[]> GetContentsOfUrl(string url)
{
Task<byte[]> bytes;
if (!_cache.TryGetValue(url, out bytes))
{
bytes = MyWebService.GetContentsAsync(url);
_cache.Add(url, bytes);
}
return bytes;
}
// это не потокобезоспасно (не копируйте себе этот код как есть)
private static Dictionary<string, Task<byte[]>> _cache = new Dictionary<string, Task<byte[]>>();
Производительность: понимайте, как await сохраняет состояние
Когда вы используете
async/await
, компилятор создаёт машину состояний, которая хранит переменные и стек. Например:public static async Task FooAsync()
{
var data = await MyWebService.GetDataAsync();
var otherData = await MyWebService.GetOtherDataAsync();
Console.WriteLine("{0} = "1", data, otherdata);
}
Это создаст объект состояния с несколькими переменными. Смотрите, как компилятор сохранит переменные метода:
[StructLayout(LayoutKind.Sequential), CompilerGenerated]
private struct <FooAsync>d__0 : <>t__IStateMachine {
private int <>1__state;
public AsyncTaskMethodBuilder <>t__builder;
public Action <>t__MoveNextDelegate;
public Data <data>5__1;
public OtherData <otherData>5__2;
private object <>t__stack;
private object <>t__awaiter;
public void MoveNext();
[DebuggerHidden]
public void <>t__SetMoveNextDelegate(Action param0);
}
Замечание 1. Если вы декларируете переменную, она сохранится в объекте, хранящем состояние. Это может привести к тому, что объекты будут оставаться в памяти дольше, чем вы бы могли ожидать.
Замечание 2. Но если вы не станете декларировать переменную, а использовать значение
Async
вызова вместе сawait
, переменная попадёт во внутренний стек:public static async Task FooAsync()
{
var data = MyWebService.GetDataAsync();
var otherData = MyWebService.GetOtherDataAsync();
// промежуточные результаты попадут во внутренний стек и
// добавятся дополнительные переключения контекстов между await-ами
Console.WriteLine("{0} = "1", await data, await otherdata);
}
Вы не должны слишком сильно волноваться по этому поводу до тех пор, пока вы не видите проблем производительности. Если вы всё-таки решили углубиться в оптимизацию, на MSDN есть хорошая статья по этому поводу: Async Performance: Understanding the Costs of Async and Await.
Стабильность: async/await – это не Task.Wait
Машина состояний, генерируемая
async/await
– это не то же самое, что Task.ContinueWith/Wait
. В общем случае вы можете заменить реализацию с Task
на await
, но могут возникнуть некоторые проблемы производительности и стабильности. Давайте посмотрим подробнее.Стабильность: знайте свой контекст синхронизации
Код .NET всегда исполняется в некотором контексте. Этот контекст определяет текущего пользователя и другие значения, требуемые фреймворком. В некоторых контекстах выполнения, код работает в контексте синхронизации, который управляет выполнением задач и другой асинхронной работы.
По-умолчанию, после
await
код продолжит работать в контексте, в котором он был запущен. Это удобно, потому что в основном вы захотите, чтобы контекст безопасности был восстановлен, и вы хотите, чтобы ваш код после await имел доступ к объектам Windows UI, если он уже имел доступ к ним при старте. Заметим, чтоTask.Factory.StartNew
– не осуществляет восстановление контекста.Некоторые контексты синхронизации не поддерживают повторный вход в них и являются однопоточными. Это означает, что только одна единица работы может выполняться в этом контексте одновременно. Примером этого может быть поток Windows UI или контекст ASP.NET.
В таких однопоточных контекстах синхронизации довольно легко получить deadlock. Если вы создадите задачу в однопоточном контексте, и потом будете ждать в этом же контексте, ваш код, который ждёт, будет блокировать выполнение фоновой задачи.
public ActionResult ActionAsync()
{
// DEADLOCK: это блокирует асинхронную задачу
// которая ждёт, когда она сможет выполняться в этом контексте
var data = GetDataAsync().Result;
return View(data);
}
private async Task<string> GetDataAsync()
{
// простой вызов асинхронного метода
var result = await MyWebService.GetDataAsync();
return result.ToString();
}
Стабильность: не используйте
Wait
, чтобы дождаться окончания задачи прямо здесьКак основное правило – если вы создаёте асинхронный код, будьте осторожны c использованием
Wait
. (c await
всё несколько лучше.)Не используйте
Wait
для задач в однопоточных контекстах синхронизации, таких как:- Потоки UI
- Контекст ASP.NET
Хорошая новость заключается в том, что фреймворк позволяет вам возвращать
Task
в определённых случаях, и сам фреймворк будет ожидать выполнения задачи. Доверье ему этот процесс:public async Task<ActionResult> ActionAsync()
{
// этот метод использует async/await и возвращает Task
var data = await GetDataAsync();
return View(data);
}
Если вы создаёте асинхронные библиотеки, ваши пользователи должны будут писать асинхронный код. Раньше это было проблемой, так как написание асинхронного кода было утомительным и уязвимым для ошибок, но с появлением
async/await
большая часть сложности теперь обрабатывается компилятором. А ваш код получает большую надёжность, и вы теперь с меньше вероятностью будете вынуждены бороться с нюансами ThreadPool
.Стабильность: рассмотрите использование
ConfigureAwait
, если вы создаёте библиотекуЕсли вы обязаны ожидать выполнения задачи в одном из этих контекстов, вы можете использовать
ConfigureAwait
, чтобы сказать системе, что она не должна выполнять фоновую задачу в вашем контексте. Недостатком этого является то, что фоновая задача не будет иметь доступа к тому же самому контексту синхронизации, так что вы потеряете доступ к Windows UI или HttpContext
(хотя ваш контекст безопасности всё равно будет у вас).Если вы создаёте «библиотечную» функцию, которая возвращает
Task
, вы, скорее всего, не знаете, как она будет вызываться. Так что, возможно, будет безопаснее добавить ConfigureAwait(false)
к вашей задаче перед тем как её вернуть.private async Task<string> GetDataAsync()
{
// ConfigureAwait(false) говорит системе, чтобы она
// позволила оставшемуся коду выполняться в любом контексте
var result = await MyWebService.GetDataAsync().ConfigureAwait(false);
return result.ToString();
}
Стабильность: понимайте, как ведут себя исключения
Когда смотришь на асинхронный код, тяжело иногда сказать, что же случается с исключениями. Будет ли оно передано вызывающей функции, или тому коду, который ждёт выполнения задачи?
Правила в этом случае довольно прямолинейны, но всё равно иногда трудно ответить на вопрос, просто глядя на код.
Некоторые примеры:
- Исключения, вызванные из самого async/await метода, будут отправлены коду, ожидающему выполнения задачи (awaiter).
public async Task<Data> GetContentsOfUrl(string url) { // это исключение будет вызвано на коде, ожидающем // выполнения этой задачи if (url == null) throw new ArgumentNullException(); var data = await MyWebService.GetContentsOfUrl(); return data.DoStuffToIt(); }
- Исключения, вызванные из делегата задачи
Task
, тоже будут отправлены коду, ожидающему выполнения задачи (awaiter).public Task<Data> GetContentsOfUrl(string url) { return Task<Data>.Factory.StartNew(() => { // это исключение будет вызвано на коде, ожидающем // выполнения этой задачи if (url == null) throw new ArgumentNullException(); var data = await MyWebService.GetContentsOfUrl(); return data.DoStuffToIt(); } }
- Исключения, вызванные во время создания Task, будут отправлены коду, который вызывал этот метод (caller) (что, в общем, очевидно):
public Task<Data> GetContentsOfUrl(string url) { // это исключение будет вызвано на вызывающем коде if (url == null) throw new ArgumentNullException(); return Task<Data>.Factory.StartNew(() => { var data = await MyWebService.GetContentsOfUrl(); return data.DoStuffToIt(); } }
Последний пример является одной из причин, почему я предпочитаю
async/await
вместо создания цепочек задач посредством Task
.Дополнительные ссылки (на английском)
- MSDN: Async/Await FAQ
- Об оптимизации await “быстрый путь”
- MSDN: Await, and UI, and deadlocks! Oh my!
- MSDN: Async Performance: Understanding the Costs of Async and Await
Подписаться на:
Сообщения (Atom)