TPLing Background worker in 10 min

Code Snippetusing System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks; namespace WpfApplication1{ public class TBackgroundWorker<TResult, TProgress> {  public static TBackgroundWorker<TResult, TProgress> New() { return new TBackgroundWorker<TResult, TProgress>(); }  public TBackgroundWorker<TResult, TProgress> StartWith(Func<object, CancellationToken, TResult> work) { Start = work; return this; }  public TBackgroundWorker<TResult, TProgress> FinishWith(Action<TResult,object> finish) { Finish = finish; return this; }  private readonly CancellationTokenSource _cancelationTokenSource; private CancellationToken _cancellationToken; private readonly TaskScheduler _uiScheduler;   public TBackgroundWorker() { _cancelationTokenSource = new CancellationTokenSource(); _uiScheduler = TaskScheduler.FromCurrentSynchronizationContext(); }  protected Func<object, CancellationToken,TResult> Start { get; set; } protected Action<TResult, object> Finish { get; set; }  public void ReportProgress(Action<TProgress> progressReport,TProgress progress) { Task.Factory.StartNew(()=>progressReport(progress),CancellationToken.None,TaskCreationOptions.None,_uiScheduler); }  public TBackgroundWorker<TResult, TProgress> Begin(object state = null) { _cancellationToken = _cancelationTokenSource.Token; Task<TResult>.Factory. StartNew(()=>Start(state,_cancellationToken),_cancellationToken). ContinueWith(x => Finish(x.Result,state), _uiScheduler);  return this; }  public void Cancel() { _cancelationTokenSource.Cancel(true); } }} usage Code Snippetusing System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes; namespace WpfApplication1{ /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { private TBackgroundWorker<string, int> _bg;  public MainWindow() { InitializeComponent(); }  private void a_Click(object sender, RoutedEventArgs e) { _bg = TBackgroundWorker<string, int>.New(). StartWith(StartSomething). FinishWith(ShowResult). Begin(); }  private void ShowResult(string obj,object state) { a.Content = obj; }  private string StartSomething(object arg, CancellationToken cancellationToken) { int i = 0; while (i < 200) { if (cancellationToken.IsCancellationRequested) { return "Cacncelled"; } i++; Thread.Sleep(50); _bg.ReportProgress(Report,i); }  return "Done"; }  private void Report(int obj) { a.Content = obj; }  private void Button_Click(object sender, RoutedEventArgs e) { _bg.Cancel(); }  }}

June 16, 2011 · 2 min · Chen Kinnrot

Prevent setting a property value after already been set

Let’s say we write an infrastructure of entities and their interaction with Nhibernate and the rest of the server side logic. We want Nhibernate to do whatever it needs. But we also want to limit the application programmer from doing crazy things, for example: Setting the Unique Identifier of an existing entity to another value. I know it sounds crazy but in a medium-sized team, anything can happen and this stuff is critical for the future. So I thought about a very KIS way to implement this kind of protection. * What I write here is the most readable version of my code, you can extract method, use interceptor, AOP, whatever works for you. private long _id; public long ID { get { return _id; } set { if (!_id.Equals(default(long)) && !_id.Equals(value)) { throw new InvalidOperationException( “You can’t set this property, it has already been set”); } _id = value; } } Very simple, easy to test, and it works with NHibernate proxy.

April 4, 2011 · 1 min · Chen Kinnrot