Async programming deep dive, with Bart de Smet
Here is a very informative presentation about the internals of await/async, which makes things a lot clearer when you are trying to understand what the hell is going on there:
Here is a very informative presentation about the internals of await/async, which makes things a lot clearer when you are trying to understand what the hell is going on there:
I have found a new addiction: prowling StackOverflow and answering questions. It does teach a lot, because you must provide in record time a quality answer that is also appreciated by the person asking the question and by the evil reviewers who hunt you down and downvote you if you mess up. OK, they're not evil, they're necessary. Assholes! :) Anyway, in honor of my 1000th point, I want to share with you the code that I have been working on for one of the questions.public class StrokeAdorner : Adorner
{
private TextBlock _textBlock;
private Brush _stroke;
private ushort _strokeThickness;
public Brush Stroke
{
get
{
return _stroke;
}
set
{
_stroke = value;
_textBlock.InvalidateVisual();
InvalidateVisual();
}
}
public ushort StrokeThickness
{
get
{
return _strokeThickness;
}
set
{
_strokeThickness = value;
_textBlock.InvalidateVisual();
InvalidateVisual();
}
}
public StrokeAdorner(UIElement adornedElement) : base(adornedElement)
{
_textBlock = adornedElement as TextBlock;
ensureTextBlock();
foreach (var property in TypeDescriptor.GetProperties(_textBlock).OfType<PropertyDescriptor>())
{
var dp = DependencyPropertyDescriptor.FromProperty(property);
if (dp == null) continue;
var metadata = dp.Metadata as FrameworkPropertyMetadata;
if (metadata == null) continue;
if (!metadata.AffectsRender) continue;
dp.AddValueChanged(_textBlock, (s, e) => this.InvalidateVisual());
}
}
private void ensureTextBlock()
{
if (_textBlock == null) throw new Exception("This adorner works on TextBlocks only");
}
protected override void OnRender(DrawingContext drawingContext)
{
ensureTextBlock();
base.OnRender(drawingContext);
var formattedText = new FormattedText(
_textBlock.Text,
CultureInfo.CurrentUICulture,
_textBlock.FlowDirection,
new Typeface(_textBlock.FontFamily, _textBlock.FontStyle, _textBlock.FontWeight, _textBlock.FontStretch),
_textBlock.FontSize,
Brushes.Black // This brush does not matter since we use the geometry of the text.
);
formattedText.TextAlignment = _textBlock.TextAlignment;
formattedText.Trimming = _textBlock.TextTrimming;
formattedText.LineHeight = _textBlock.LineHeight;
formattedText.MaxTextWidth = _textBlock.ActualWidth - _textBlock.Padding.Left - _textBlock.Padding.Right;
formattedText.MaxTextHeight = _textBlock.ActualHeight - _textBlock.Padding.Top;// - _textBlock.Padding.Bottom;
while (formattedText.Extent==double.NegativeInfinity)
{
formattedText.MaxTextHeight++;
}
// Build the geometry object that represents the text.
var _textGeometry = formattedText.BuildGeometry(new Point(_textBlock.Padding.Left, _textBlock.Padding.Top));
var textPen = new Pen(Stroke, StrokeThickness);
drawingContext.DrawGeometry(Brushes.Transparent, textPen, _textGeometry);
}
}
public static class Adorningand an example of use:
{
public static Brush GetStroke(DependencyObject obj)
{
return (Brush)obj.GetValue(StrokeProperty);
}
public static void SetStroke(DependencyObject obj, Brush value)
{
obj.SetValue(StrokeProperty, value);
}
// Using a DependencyProperty as the backing store for Stroke. This enables animation, styling, binding, etc...
public static readonly DependencyProperty StrokeProperty =
DependencyProperty.RegisterAttached("Stroke", typeof(Brush), typeof(Adorning), new PropertyMetadata(Brushes.Transparent, strokeChanged));
private static void strokeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var stroke= e.NewValue as Brush;
ensureAdorner(d,a=>a.Stroke=stroke);
}
private static void ensureAdorner(DependencyObject d, Action<StrokeAdorner> action)
{
var tb = d as TextBlock;
if (tb == null) throw new Exception("StrokeAdorner only works on TextBlocks");
EventHandler f = null;
f = new EventHandler((o, e) =>
{
var adornerLayer = AdornerLayer.GetAdornerLayer(tb);
if (adornerLayer == null) throw new Exception("AdornerLayer should not be empty");
var adorners = adornerLayer.GetAdorners(tb);
var adorner = adorners == null ? null : adorners.OfType<StrokeAdorner>().FirstOrDefault();
if (adorner == null)
{
adorner = new StrokeAdorner(tb);
adornerLayer.Add(adorner);
}
tb.LayoutUpdated -= f;
action(adorner);
});
tb.LayoutUpdated += f;
}
public static double GetStrokeThickness(DependencyObject obj)
{
return (double)obj.GetValue(StrokeThicknessProperty);
}
public static void SetStrokeThickness(DependencyObject obj, double value)
{
obj.SetValue(StrokeThicknessProperty, value);
}
// Using a DependencyProperty as the backing store for StrokeThickness. This enables animation, styling, binding, etc...
public static readonly DependencyProperty StrokeThicknessProperty =
DependencyProperty.RegisterAttached("StrokeThickness", typeof(double), typeof(Adorning), new PropertyMetadata(0.0, strokeThicknessChanged));
private static void strokeThicknessChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ensureAdorner(d, a =>
{
if (DependencyProperty.UnsetValue.Equals(e.NewValue)) return;
a.StrokeThickness = (ushort)(double)e.NewValue;
});
}
}
<TextBlock
x:Name="t1"
HorizontalAlignment="Stretch"
FontSize="40"
FontWeight="Bold"
local:Adorning.Stroke="Red"
local:Adorning.StrokeThickness="2"
Text="Some text that needs to be outlined"
TextAlignment="Center"
TextWrapping="Wrap"
Width="600">
<TextBlock.Foreground>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Offset="0" Color="Green" />
<GradientStop Offset="1" Color="Blue" />
</LinearGradientBrush>
</TextBlock.Foreground>
</TextBlock>
foreach (var property in TypeDescriptor.GetProperties(_textBlock).OfType<PropertyDescriptor>())Here I am enumerating each property of the target (the TextBlock) and checking if they are dependency properties and if they have in their metadata the AffectsRender flag, they I add a property change handler which calls InvalidateVisual on the adorner. Notice that in no part of the code do I remove those handlers. However, at this time I don't think it is a problem. Anyway, the code itself is more about the principles of the thing, rather than the implementation.
{
var dp = DependencyPropertyDescriptor.FromProperty(property);
if (dp == null) continue;
var metadata = dp.Metadata as FrameworkPropertyMetadata;
if (metadata == null) continue;
if (!metadata.AffectsRender) continue;
dp.AddValueChanged(_textBlock, (s, e) => this.InvalidateVisual());
}
Inspired by my own post about simulating F# active patterns in C# and remembering an old crazy post about using try/catch to emulate a switch on types, I came up with this utility class that acts and looks like a switch statement, but can do a lot more. The basic idea was to use a fluent interface to get the same functionality of switch, but also add the possibility of using complex objects as case values or even code conditions. namespace ConstructsI use the static class Do to very easily get a Switch<T> object based on a value, then run actions on that value. The Switch class has a _value field and an _isDone field. When _isDone is set to true, no action is further executed (like breaking from a switch block). The class has the methods Case, and If, as well as OfType and OfStrictType, all of which execute an action if either the value, the function, the condition or the type provided match the initial value. Default is always last, executing an action and setting _isDone to true;
{
public static class Do
{
public static Switch<T> Switch<T>(T value)
{
return Constructs.Switch<T>.From(value);
}
}
public class Switch<T>
{
private bool _isDone;
private T _value;
private Type _valueType;
private Switch(T value)
{
this._value = value;
}
public static Switch<T> From(T value)
{
return new Switch<T>(value);
}
public Switch<T> Case(Func<T> valueFunc, Action<T> action, bool fallThrough = false)
{
if (_isDone) return this;
return Case(valueFunc(), action, fallThrough);
}
public Switch<T> Case(T value, Action<T> action, bool fallThrough = false)
{
if (_isDone) return this;
return If(v => object.Equals(value, v), action, fallThrough);
}
public void Default(Action<T> action)
{
if (_isDone) return;
action(_value);
}
public Switch<T> If(Func<T, bool> boolFunc, Action<T> action, bool fallThrough = false)
{
if (_isDone) return this;
if (boolFunc(_value))
{
action(_value);
_isDone = !fallThrough;
}
return this;
}
private Type getValueType()
{
if (_valueType != null) return _valueType;
if (object.Equals(_value, null)) return null;
_valueType = _value.GetType();
return _valueType;
}
public Switch<T> OfStrictType<TType>(Action<T> action, bool fallThrough = false)
{
if (_isDone) return this;
if (getValueType() == typeof(TType))
{
action(_value);
_isDone = !fallThrough;
}
return this;
}
public Switch<T> OfType<TType>(Action<T> action, bool fallThrough = false)
{
if (_isDone) return this;
if (getValueType() == null) return this;
if (typeof(TType).IsAssignableFrom(getValueType()))
{
action(_value);
_isDone = !fallThrough;
}
return this;
}
}
}
for (var i = 0; i < 25; i++)where the numbers from 0 to 25 are compared with 10, the half of the minutes value of the current time and checked if they are divisible by 7, else they are simply displayed. Note that the first two Case methods receive an optional bool parameter that allows the check to fall through, so that the value is checked if it is equal to 10, but also if it is twice the minute value or divisible by 7. On the other hand, if the value is divisible by 7 it will not display the value in the Default method.
{
Do.Switch(i)
.Case(10, v => Console.WriteLine("i is ten"), true)
.Case(() => DateTime.Now.Minute / 2, v =>
Console.WriteLine($"i is the same with half of the minute of the time ({v})"), true)
.If(v => v % 7 == 0, v => Console.WriteLine($"{v} divisible by 7"))
.Default(v => Console.WriteLine($"{v}"));
}
var f = new Action<object>(x =>
Do.Switch(x)
.OfType<string>(v => Console.WriteLine($"{v} is a string"))
.OfType<DateTime>(v => Console.WriteLine($"{v} is a DateTime"))
.OfType<int>(v => Console.WriteLine($"{v} is an integer"))
.OfType<object>(v => Console.WriteLine($"{v} is an object"))
);
f(DateTime.Now);
f("Hello, world!");
f(13);
f(0.45);
for (var i = 0; i < 100; i++)
{
Do.Switch(i)
.If(v => v % 15 == 0, v => Console.WriteLine($"FizzBuzz"))
.If(v => v % 3 == 0, v => Console.WriteLine($"Fizz"))
.If(v => v % 5 == 0, v => Console.WriteLine($"Buzz"))
.Default(v => Console.WriteLine($"{v}"));
}
F# has an interesting feature called Active Patterns. I liked the idea and started thinking how I would implement this in C#. It all started from this StackOverflow question to which only Scala answers were given at the time.// create an active pattern
let (|Int|_|) str =
match System.Int32.TryParse(str) with
| (true, int) -> Some(int)
| _ -> None
// create an active pattern
let (|Bool|_|) str =
match System.Boolean.TryParse(str) with
| (true, bool) -> Some(bool)
| _ -> None
// create a function to call the patterns
let testParse str =
match str with
| Int i -> printfn "The value is an int '%i'" i
| Bool b -> printfn "The value is a bool '%b'" b
| _ -> printfn "The value '%s' is something else" str
// test
testParse "12"
testParse "true"
testParse "abc"
var apInt = new Func<string, Option<int>>(s =>
{
int i;
if (System.Int32.TryParse(s, out i)) return new Option<int>(i);
return Option<int>.Empty;
});
var apBool = new Func<string, Option<bool>>(s =>
{
bool b;
if (System.Boolean.TryParse(s, out b)) return new Option<bool>(b);
return Option<bool>.Empty;
});
var testParse = new Action<string>(s =>
{
var oi = apInt(s);
if (oi.HoldsValue)
{
Console.WriteLine($"The value is an int '{oi.Value}'");
return;
}
var ob = apBool(s);
if (ob.HoldsValue)
{
Console.WriteLine($"The value is an bool '{ob.Value}'");
return;
}
Console.WriteLine($"The value '{s}' is something else");
});
testParse("12");
testParse("true");
testParse("abc");
var apInt = Option<int>.From<string>(s =>
{
int i;
return System.Int32.TryParse(s, out i)
? new Option<int>(i)
: Option<int>.Empty;
});
var apBool = Option<bool>.From<string>(s =>
{
bool b;
return System.Boolean.TryParse(s, out b)
? new Option<bool>(b)
: Option<bool>.Empty;
});
var testParse = new Action<string>(s =>
{
FluidFunc
.Match(s)
.With(apInt, r => Console.WriteLine($"The value is an int '{r}'"))
.With(apBool, r => Console.WriteLine($"The value is an bool '{r}'"))
.Else(v => Console.WriteLine($"The value '{v}' is something else"));
});
testParse("12");
testParse("true");
testParse("abc");
var apInt = FluidFunc.From<string,int>(s =>
{
int i;
return System.Int32.TryParse(s, out i)
? new Tuple<bool, int>(true, i)
: new Tuple<bool, int>(false, 0);
});
var apBool = FluidFunc.From<string,bool>(s =>
{
bool b;
return System.Boolean.TryParse(s, out b)
? new Tuple<bool, bool>(true, b)
: new Tuple<bool, bool>(false, false);
});
var testParse = new Action<string>(s =>
{
FluidFunc
.Match(s)
.With(apInt, r => Console.WriteLine($"The value is an int '{r}'"))
.With(apBool, r => Console.WriteLine($"The value is an bool '{r}'"))
.Else(v => Console.WriteLine($"The value '{v}' is something else"));
});
testParse("12");
testParse("true");
testParse("abc");
public static class FluidFunc
{
public static FluidFunc<TInput> Match<TInput>(TInput value)
{
return FluidFunc<TInput>.With(value);
}
public static Func<TInput, Tuple<bool, TResult>> From<TInput, TResult>(Func<TInput, Tuple<bool, TResult>> func)
{
return func;
}
}
public class FluidFunc<TInput>
{
private TInput _value;
private static FluidFunc<TInput> _noOp;
private bool _isNoop;
public static FluidFunc<TInput> NoOp
{
get
{
if (_noOp == null) _noOp = new FluidFunc<TInput>();
return _noOp;
}
}
private FluidFunc()
{
this._isNoop = true;
}
private FluidFunc(TInput value)
{
this._value = value;
}
public static FluidFunc<TInput> With(TInput value)
{
return new FluidFunc<TInput>(value);
}
public FluidFunc<TInput> With<TNew>(Func<TInput, Option<TNew>> func, Action<TNew> action)
{
if (this._isNoop)
{
return this;
}
var result = func(_value);
if (result.HoldsValue)
{
action(result.Value);
return FluidFunc<TInput>.NoOp;
}
return new FluidFunc<TInput>(_value);
}
public FluidFunc<TInput> With<TNew>(Func<TInput, Tuple<bool,TNew>> func, Action<TNew> action)
{
if (this._isNoop)
{
return this;
}
var result = func(_value);
if (result.Item1)
{
action(result.Item2);
return FluidFunc<TInput>.NoOp;
}
return new FluidFunc<TInput>(_value);
}
public void Else(Action<TInput> action)
{
if (this._isNoop) return;
action(_value);
}
}
On the 9th of February I basically held the same talk I did at Impact Hub, only I did better, and this time presented to the ADCES group. Unbeknownst to me, my colleague there Andrei Rînea also held a similar presentation with the same organization, more than two years ago, and it is quite difficult to assume that I was not inspired by it when one notices how similar they really were :) Anyway, that means there is no way people can say they didn't get it, now! Here is his blog entry about that presentation: Bing it on, Reactive Extensions! – story, code and slides
This post is discussing the solution to the NotSupportedException "This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread" and also the InvalidOperationException "An ItemsControl is inconsistent with its items source".BindingOperations.EnableCollectionSynchronization(collection, lockObject);This short blog post from Florent Pellet explains things a little, but that is ending on a dire note:
The ViewModel becomes dependent on the viewIt also suggests that you need to create a lock object for each UI thread, if you have more.
When you call this overload of the EnableCollectionSynchronization(IEnumerable, Object) method, the system locks the collection when you access it, which implies you are losing some performance, but not much else. In case you have many parallel threads that are modifying your collection, you need to lock it, anyway. You may, of course, create your own high performance system of changing a collection and, maybe, run a separate method to marshal changes from your private data structure to the UI bound one.
BindingOperations.EnableCollectionSynchronization(collection, lockObject);Funny enough, you have to run this piece of code on the Dispatcher UI thread.
Today I was the third presenter in the ReactiveX in Action event, held at Impact Hub, Bucharest. The presentation did not go as well as planned, but was relatively OK. I have to say that probably, after a while, giving talks to so many people turns from terrifying to exciting and then to addictive. Also, you really learn things better when you are preparing to teach them later, rather than just perusing them.
Stephen Toub wrote this document, as he calls it, but that is so full of useful information that it can be considered a reference book. A 118 pages PDF, Patterns for Parallel Programming taught me a lot of things about .NET parallel programming (although most of them I should have known already :-().
On the 3rd and 9th of February I will be presenting a demo of Reactive Extension in action on a Windows Presentation Foundation app that I am going to be building as I speak, first without and then with Rx. The presentation should be about 30-45 minutes, in Romanian, but I am sure we can accommodate foreign speakers by doing it in English if you request it. These events are all free, but you must register in order to know how many people to prepare for. Here are the Meetup links:
Some of you may have heard of C# 6, the new version of the Microsoft .NET programming language, but what I am not certain about is that you know you can use it right now. I had expected that a new version of the language will be usable from the brand new upcoming fifth version of the .NET runtime, but actually no, you can use it right now in your projects, because the new features have been implemented in the compiler, in Visual Studio and, you have no idea how cool it is until you try, in ReSharper.public int Count {
get {
return _innerList.Count;
}
}
public int Count => _innerList.Count;Cool or what?
if (Granddaddy!=null) {
if (Daddy!=null) {
if (Child!=null) {
return Grandaddy.Daddy.Child.SomeStupidProperty;
}
}
}
return Grandaddy?.Daddy?.Child?.SomeStupidProperty;Convinced yet?
public int Number {
get { return _number; }
set {
if (_number!=value) {
_number=value;
OnPropertyChanged("Number");
//with some custom code you could have used a better, but slower version:
//OnPropertyChanged(()=>Number);
}
}
}
public int Number {
get { return _number; }
set {
if (_number!=value) {
_number=value;
OnPropertyChanged(nameof(Number));
// this assumes that we have a base class with a method called OnPropertyChaged, but we can already to things inline:
PropertyChanged?.Invoke(this,new new PropertyChangedEventArgs(nameof(Number))
}
}
}
public override string ToString() {
return string.Format("{0}, {1}", First, Second);
}
public override string ToString() => $"{First}, {Second}";
try {
SomethingUnpredictable();
}
catch (Exception e) {
if (e.InnerException!=null) {
UnpackAndLogException(e);
} else {
throw;
}
}
try {
SomethingUnpredictable();
}
catch (Exception e) when (e.InnerException!=null) {
UnpackAndLogException(e);
}
return degrees*Math.PI/180;//somewhere above:
using static System.Math;
return degrees*PI/180;
There are a lot of people asking around what is the difference between BindingList<T> and ObservableCollection<T> and therefore, there are a lot of answers. I am writing this entry so that next time I look it up, I save StackOverflow some bandwidth. Also, because my blog is cooler :)
I've come upon this strange Not enough storage is available to complete this operationArgumentException when creating an instance of EventSource derived classes. This class is responsible for creating entries in Windows logs. Strangely enough, there are very few articles on the Internet connecting the class with this particular exception, so I started to investigate. One important thing to notice is that the exception is intermittent. Basically you can cycle a few times with a try/catch block and get a valid instance. That seems to indicate some sort of race condition. So far, this is the easy solution I could find. However, I really wanted to know why does it happen.
LoggerEventSource eventSource = null; //EventSource derived class (see documentation)
for (var i = 0; i < 5 && eventSource == null; i++)
{
try
{
eventSource = new LoggerEventSource();
}
catch (ArgumentException)
{
Thread.Sleep(100);
}
}
I had this situation where I had to execute large SQL script files and the default sqlcmd tool was throwing exceptions rather than execute them. So I created my own tool to read the scripts and execute them transactionally. Everything went smoothly, except at the end. You see, I didn't use TransactionScope.Complete from the beginning in order to see how the program would cope with a massive rollback. Not well, apparently.Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. I had set the TransactionOptions.Timeout to TransactionManager.MaximumTimeout and the SqlCommand.CommandTimeout to 0 (meaning never end) and I still got the exception. Apparently, the problem was the SqlConnection.ConnectTimeout which is a readonly property with a default value of 15 seconds. The value can be changed via the connection string, by adding something like Connect Timeout=36000 (10 hours) and many articles on the Internet suggest doing that. However, that is just really ugly. A better solution is to set the value of the timeout programmatically and this is how to do it:
var timeout = TimeSpan.FromHours(10);
SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder(connectionString);
csb.ConnectTimeout = (int)timeout.TotalSeconds;
connectionString = csb.ConnectionString;
I needed to get all IP addresses in a range, so I applied the mask to my current IP and started to work through the minimum and maximum values of bytes to get the result. I had a code that looked like this: for (var b = min; b <= max; b++) { //do stuff }where min was 0 and max was 255.
As you know from the previous post, I am working on a network monitor application that displays information about the devices in my local network. For that I need to ping them to see if they are available. The simplest solution is to use the out-of-the-box solution of System.Net.NetworkInformation.Ping. It was no little shock to stop debugging my application and find myself facing a Blue Screen of Death, you know, the blue thing with white text that means everything is fucked, with the error message PROCESS_HAS_LOCKED_PAGES.