Events in C# 4.0
March 31, 2010 Leave a comment
…for when my brain gets too full.
March 31, 2010 Leave a comment
March 20, 2010 1 Comment
Rx is a set of framework extensions to allow developers to easily do asynchronous programming via familiar interfaces. If you are familiar with LINQ and IEnumerable<T> and IEnumerator<T> you will instantly be able to grasp and use the new interfaces IObservable<T> and IObserver<T>. The enumerating interfaces allow you to PULL sequences of T from an interface in your code. The observing interfaces allow you to have sequences of T PUSHED to handlers in your code in response to asynchronous LINQ queries. Rx is implemented over the top of PFx (Parallel Framework extensions) so all the threading and concurrency is handled for you including synchronization contexts which is especially useful if you are programming UI. It is also particularly significant that the Rx extension methods include a FromEvent() method that allows you to attach handlers to a steam of events in a very fluid way.
If you want to know more watch the video on the bottom of this page where Rx author Erik Meijer explains it in 14 minutes.
If you want to see it in action have a look at this Channel9 video with Wes Dyer where he implements drag & drop from scratch using Rx in 6 minutes.
Also, checkout the Rx Team Blog for downloads, updates and samples.
Finally, back to Channel9 to look at RxJS for Reactive extensions for Java Script so the UI I mentioned above now includes web UI too. As Jeffrey Van Gogh says in the RxJS video, web programming is about “asynchronous stuff” but java script is an imperative language. It’s really hard to do good asynchronous stuff in java script. RxJS changes that it a big way.
April 6, 2009 Leave a comment
Speaking of scale there’s an interesting article here by Bart Smaalders of Sun Microsystems about performance anti-patterns. He has identified a number of these anti-patterns :
Although it does appear to have been written from the perspective of “performance over all” and some sections (e.g. the one about layering) ignore that fact that the history of software development has been a gradual trade-off between performance and other equally important things like flexibility, maintainability, portability, modularity, productivity etc, it’s a short, well written article that makes interesting reading.
January 13, 2009 Leave a comment
The NSA, with contributions from, among others, :
have published a list of the 25 most dangerous programming errors that lead to security bugs and that enable cyber espionage and cyber crime.
Shockingly, most of these errors are not well understood by programmers; their avoidance is not widely taught by computer science programs; and their presence is frequently not tested by organizations developing software for sale.
These Top 25 Errors are divided in three categories:
The list will be constantly updated and augmented with resources to help combat/prevent these errors.
Full article here : http://www.sans.org/top25errors/
Full list here : http://cwe.mitre.org/top25/
May 31, 2008 Leave a comment
[ServiceContract()] public interface IMyService { [OperationContract] [DebuggableSerializer] Thing GetThing(Flavour flavour); [OperationContract] [DebuggableSerializer] Thing[] GetOneOfEach(); }
[DebuggableSerializer] public Thing[] GetOneOfEach() { List<Thing> things = new List<Thing>(); foreach(Flavour f in Enum.GetValues(typeof(Flavour))) { things.Add(this.GetThing(f)); } return things.ToArray(); }
public class DebuggableSerializer : Attribute, IOperationBehavior
public class DebuggableSerializer : Attribute, IOperationBehavior, IServiceBehavior, IEndpointBehavior, IContractBehavior
#region IServiceBehavior Members public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { ReplaceDataContractSerializerOperationBehavior(serviceDescription); } public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { ReplaceDataContractSerializerOperationBehavior(serviceDescription); } public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } #endregion #region IEndpointBehavior Members public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { ReplaceDataContractSerializerOperationBehavior(endpoint); } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { ReplaceDataContractSerializerOperationBehavior(endpoint); } public void Validate(ServiceEndpoint endpoint) { } #endregion #region IContractBehavior Members public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime) { ReplaceDataContractSerializerOperationBehavior(contractDescription); } public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) { ReplaceDataContractSerializerOperationBehavior(contractDescription); } public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint) { } #endregion
private static void ReplaceDataContractSerializerOperationBehavior( ServiceDescription description) { foreach (ServiceEndpoint endpoint in description.Endpoints) { ReplaceDataContractSerializerOperationBehavior(endpoint); } } private static void ReplaceDataContractSerializerOperationBehavior( ContractDescription description) { foreach (OperationDescription desc in description.Operations) { ReplaceDataContractSerializerOperationBehavior(desc); } } private static void ReplaceDataContractSerializerOperationBehavior( ServiceEndpoint endpoint) { // ignore mex if (endpoint.Contract.ContractType == typeof(IMetadataExchange)) { return; } ReplaceDataContractSerializerOperationBehavior(endpoint.Contract); }
[DebuggableSerializer] public class MyService : IMyService { ... } [DebuggableSerializer] public interface IMyService { ... }
public class UseDebuggableSerializer : BehaviorExtensionElement { public override Type BehaviorType { get { return typeof(DebuggableSerializer); } } protected override object CreateBehavior() { return new DebuggableSerializer(); } }
<system.serviceModel> <extensions> <behaviorExtensions> <add name="UseDebuggableSerializer" type="WCFLibrary.UseDebuggableSerializer, WCFLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> </behaviorExtensions> </extensions> <!-- elided --> </system.serviceModel>
<system.serviceModel> <!-- elided --> <behaviors> <serviceBehaviors> <behavior name="MetadataExchange"> <serviceMetadata httpGetEnabled="true" /> <UseDebuggableSerializer /> </behavior> </serviceBehaviors> </behaviors> <!-- elided --> </system.serviceModel>
<system.serviceModel> <!-- elided --> <behaviors> <endpointBehaviors> <behavior name="DebuggableSerializer"> <UseDebuggableSerializer /> </behavior> </endpointBehaviors> </behaviors> <!-- elided --> <service behaviorConfiguration="MetadataExchange" name="WCFLibrary.MyService"> <endpoint address="net.tcp://localhost:7000/MyService" behaviorConfiguration="DebuggableSerializer" binding="netTcpBinding" name="TCP_7000_MyService" contract="WCFLibrary.IMyService" /> </service> <!-- elided --> </system.serviceModel>
May 28, 2008 2 Comments
using System; using System.Collections.Generic; using System.Text; using System.ServiceModel; using System.Runtime.Serialization; namespace WCFLibrary { [ServiceContract()] public interface IMyService { [OperationContract] Thing GetThing(Flavour flavour); [OperationContract] Thing[] GetOneOfEach(); } public class MyService : IMyService { #region IMyService Members public Thing GetThing(Flavour flavour) { switch (flavour) { case Flavour.Orange: return new Thing("Ollie", Flavour.Orange); case Flavour.Raspberry: return new Thing("Roger", Flavour.Raspberry); case Flavour.Strawberry: return new Thing("Sally", Flavour.Strawberry); case Flavour.Banana: return new Thing("Bernice", Flavour.Banana); default: throw new FaultException("No such flavour"); } } public Thing[] GetOneOfEach() { List<Thing> things = new List<Thing>(); foreach(Flavour f in Enum.GetValues(typeof(Flavour))) { things.Add(this.GetThing(f)); } return things.ToArray(); } #endregion } public enum Flavour { Strawberry, Raspberry, Orange, Banana } [DataContract] public class Thing { string name; Flavour flavour; public Thing(string name, Flavour flavour) { this.Name = name; this.Flavour = flavour; } [DataMember] public string Name { get { return name; } set { name = value; } } [DataMember] public Flavour Flavour { get { return flavour; } set { flavour = value; } } } }
using System; using System.Collections.Generic; using System.Text; using System.ServiceModel; namespace WCFHost { class Program { static void Main(string[] args) { using (ServiceHost host = new ServiceHost( typeof(WCFLibrary.MyService), new Uri("http://localhost:7001/MyService"))) { host.Closed += new EventHandler(host_Closed); host.Open(); Console.WriteLine( "{0} is running at {1}.\nPress any key to close and exit...", host.Description.ServiceType.FullName, host.BaseAddresses[0].ToString()); Console.ReadKey(true); } } static void host_Closed(object sender, EventArgs e) { Console.WriteLine("{0} closed.", ((ServiceHost)sender).Description.ServiceType.FullName); } } }
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="MetadataExchange"> <serviceMetadata httpGetEnabled="true" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="MetadataExchange" name="WCFLibrary.MyService"> <endpoint address="net.tcp://localhost:7000/MyService" binding="netTcpBinding" bindingConfiguration="" name="TCP_7000_MyService" contract="WCFLibrary.IMyService" /> </service> </services> </system.serviceModel> </configuration>
using System; using System.Collections.Generic; using System.Text; using WCFClient.MyService; namespace WCFClient { class Program { static void Main(string[] args) { using (MyServiceClient proxy = new MyServiceClient()) { foreach (Thing thing in proxy.GetOneOfEach()) { Console.WriteLine("{0} {1}", thing.Name, thing.Flavour.ToString()); } } Console.ReadKey(true); } } }
case Flavour.Banana: return new Thing("Bernice", Flavour.Banana);
case Flavour.Banana: return new Thing("Bernice", (Flavour)9);
return new Thing("Bernice", (Flavour)reader.GetInt32(3));
<system.diagnostics> <sources> <source name="System.ServiceModel" switchValue="Verbose,ActivityTracing" propagateActivity="true"> <listeners> <add type="System.Diagnostics.DefaultTraceListener" name="Default"> <filter type="" /> </add> <add name="ServiceModelTraceListener"> <filter type="" /> </add> </listeners> </source> </sources> <sharedListeners> <add initializeData="c:\temp\app_tracelog.svclog" type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" name="ServiceModelTraceListener" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack"> <filter type="" /> </add> </sharedListeners> </system.diagnostics>
public class DebuggableDataContractSerializer : XmlObjectSerializer { private XmlObjectSerializer _Serializer; public DebuggableDataContractSerializer(XmlObjectSerializer serializerToUse) { if (serializerToUse == null) { throw new ArgumentException("Argument cannot be null.", "serializerToUse"); } this._Serializer = serializerToUse; } public override bool Equals(object obj) { return this._Serializer.Equals(obj); } public override bool IsStartObject(XmlDictionaryReader reader) { return this._Serializer.IsStartObject(reader); } public override object ReadObject(XmlDictionaryReader reader) { return this._Serializer.ReadObject(reader); } public override object ReadObject(XmlReader reader) { return this._Serializer.ReadObject(reader); } public override object ReadObject(XmlReader reader, bool verifyObjectName) { return this._Serializer.ReadObject(reader, verifyObjectName); } public override string ToString() { return this._Serializer.ToString(); } public override int GetHashCode() { return this._Serializer.GetHashCode(); } public override bool IsStartObject(XmlReader reader) { return this._Serializer.IsStartObject(reader); } public override object ReadObject(System.IO.Stream stream) { return this._Serializer.ReadObject(stream); } public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName) { return this._Serializer.ReadObject(reader, verifyObjectName); } public override void WriteEndObject(XmlDictionaryWriter writer) { this._Serializer.WriteEndObject(writer); } public override void WriteEndObject(XmlWriter writer) { this._Serializer.WriteEndObject(writer); } public override void WriteObject(System.IO.Stream stream, object graph) { this._Serializer.WriteObject(stream, graph); } public override void WriteObject(XmlDictionaryWriter writer, object graph) { this._Serializer.WriteObject(writer, graph); } public override void WriteObject(XmlWriter writer, object graph) { this._Serializer.WriteObject(writer, graph); } public override void WriteObjectContent(XmlDictionaryWriter writer, object graph) { this._Serializer.WriteObjectContent(writer, graph); } public override void WriteObjectContent(XmlWriter writer, object graph) { this._Serializer.WriteObjectContent(writer, graph); } public override void WriteStartObject(XmlDictionaryWriter writer, object graph) { this._Serializer.WriteStartObject(writer, graph); } public override void WriteStartObject(XmlWriter writer, object graph) { this._Serializer.WriteStartObject(writer, graph); } }
public class DebuggableSerializer : Attribute, IOperationBehavior { public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters) { } public void ApplyClientBehavior(OperationDescription description, ClientOperation proxy) { ReplaceDataContractSerializerOperationBehavior(description); } public void ApplyDispatchBehavior(OperationDescription description, DispatchOperation dispatch) { ReplaceDataContractSerializerOperationBehavior(description); } public void Validate(OperationDescription description) { } private static void ReplaceDataContractSerializerOperationBehavior( OperationDescription description) { DataContractSerializerOperationBehavior dcsOperationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>(); if (dcsOperationBehavior != null) { description.Behaviors.Remove(dcsOperationBehavior); description.Behaviors.Add( new DebuggableDataContractSerializerOperationBehavior(description)); } } } public class DebuggableDataContractSerializerOperationBehavior : DataContractSerializerOperationBehavior { public DebuggableDataContractSerializerOperationBehavior( OperationDescription operationDescription) : base(operationDescription) { } public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes) { DataContractSerializer dcs = new DataContractSerializer(type, name, ns, knownTypes); DebuggableDataContractSerializer mdcs = new DebuggableDataContractSerializer(dcs); return mdcs; } public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes) { DataContractSerializer dcs = new DataContractSerializer(type, name, ns, knownTypes); DebuggableDataContractSerializer mdcs = new DebuggableDataContractSerializer(dcs); return mdcs; } }
[ServiceContract()] public interface IMyService { [OperationContract] [DebuggableSerializer] Thing GetThing(Flavour flavour); [OperationContract] [DebuggableSerializer] Thing[] GetOneOfEach(); }
May 21, 2008 Leave a comment
<RewriterRule> <LookFor>.*/MyNiceURL.aspx</LookFor> <SendTo>~/Default.aspx?tabid=1234</SendTo> </RewriterRule>
<RewriterRule Type="Permanent"> <LookFor>.*/MyNiceURL.aspx</LookFor> <SendTo>~/Default.aspx?tabid=1234</SendTo> </RewriterRule>
<RewriterRule> <LookFor>.*/MyNiceURL.aspx</LookFor> <SendTo>http://www.mydomain.com/Default.aspx?tabid=1234</SendTo> </RewriterRule>
Public Enum RewriterRuleType Rewrite = 0 Permanent = 1 Temporary = 2 End Enum
Private _ruleType As RewriterRuleType = RewriterRuleType.Rewrite Public Property RuleType() As RewriterRuleType Get Return _ruleType End Get Set(ByVal Value As RewriterRuleType) _ruleType = Value End Set End Property
... For Each nav As XPathNavigator In doc.CreateNavigator.Select("RewriterConfig/Rules/RewriterRule") Dim rule As New RewriterRule() rule.LookFor = nav.SelectSingleNode("LookFor").Value rule.SendTo = nav.SelectSingleNode("SendTo").Value ' >>> begin new code Try rule.RuleType = CType(System.Enum.Parse(GetType(RewriterRuleType), nav.GetAttribute("Type", ""), False), RewriterRuleType) Catch ex As Exception ' Do nothing, either there was no attribute or it contained an invalid value ' NB : yes this is a dirty hack but this is a blog post not production code End Try ' >>> end new code Config.Rules.Add(rule) Next ...
... If intMatch <> -1 Then ' >>> begin new code Select Case (ruleType) Case Config.RewriterRuleType.Permanent RewriterUtils.PermanentlyRedirectURL(app.Context, sendTo) Case Config.RewriterRuleType.Rewrite ' >>> begin old code If rules(intMatch).SendTo.StartsWith("~") Then ' rewrite the URL for internal processing RewriterUtils.RewriteUrl(app.Context, sendTo) Else ' it is not possible to rewrite the domain portion of the URL so redirect to the new URL Response.Redirect(sendTo, True) End If ' >>> end old code Case Config.RewriterRuleType.Temporary RewriterUtils.TemporarilyRedirectURL(app.Context, sendTo) End Select ' >>> end new code End If ...
Friend Shared Sub TemporarilyRedirectURL(ByVal context As HttpContext, ByVal sendToUrl As String) context.Response.Clear() context.Response.Status = "302 Found" context.Response.AddHeader("Location", sendToUrl) context.Response.End() End Sub Friend Shared Sub PermanentlyRedirectURL(ByVal context As HttpContext, ByVal sendToUrl As String) context.Response.Clear() context.Response.Status = "301 Moved Permanently" context.Response.AddHeader("Location", sendToUrl) context.Response.End() End Sub
May 11, 2008 Leave a comment
Now, I mentioned the flick of a switch in the service config to enable this feature which is off by default, so here it is :
<system.serviceModel> <diagnostics wmiProviderEnabled="false" performanceCounters="All" /> <!-- ... your other service config here... --> </system.serviceModel>
using System; using System.ServiceModel; using System.Runtime.Serialization; namespace WCFTestService { [ServiceContract] public interface IMyService { [OperationContract] Foo GetFoo(); [OperationContract] void SetFoo(Foo foo); } [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] public class MyService : IMyService { #region IMyService Members public Foo GetFoo() { System.Threading.Thread.Sleep(200); return new Foo("Hello"); } public void SetFoo(Foo foo) { System.Threading.Thread.Sleep(200); Console.WriteLine("Bar = " + foo.Bar); } #endregion } [DataContract] public class Foo { public Foo(string bar) { this.Bar = bar; } private string _Bar = string.Empty; [DataMember] public string Bar { get { return this._Bar; } set { this._Bar = value; } } } }
using System; using System.ServiceModel; namespace WCFTestHost { class Program { static void Main(string[] args) { ServiceHost host = new ServiceHost(typeof(WCFTestService.MyService), new Uri("http://localhost:7001/MyService")); host.Open(); Console.WriteLine("Service Running. Press any key to exit..."); Console.ReadKey(); } } }
…and here is the config for the host executable :
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <diagnostics wmiProviderEnabled="false" performanceCounters="All" /> <behaviors> <serviceBehaviors> <behavior name="MetadataExchange"> <serviceMetadata httpGetEnabled="true" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="MetadataExchange" name="WCFTestService.MyService"> <endpoint address="net.tcp://localhost:7000/MyService" binding="netTcpBinding" contract="WCFTestService.IMyService" /> </service> </services> </system.serviceModel> </configuration>
using System; using System.Collections.Generic; using System.Threading; using WCFTestClient.WCFTestService; namespace WCFTestClient{ class Program { static void Main(string[] args) { try { WaitCallback fire = delegate(object proxy) { Random r = new Random(System.Environment.TickCount); int i = r.Next(1,3); if (i==1) { string s = ((MyServiceClient)proxy).GetFoo().Bar; Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + " : " + s); } else { ((MyServiceClient)proxy).SetFoo(new Foo(){Bar = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString()}); } using (proxy as IDisposable) { } }; Action<MyServiceClient> queueUp = delegate(MyServiceClient proxy) { ThreadPool.QueueUserWorkItem(fire, proxy); }; List<MyServiceClient> proxies = new List<MyServiceClient>(); for (int i = 0; i < 100; i++) { proxies.Add(new MyServiceClient()); } proxies.ForEach(queueUp); } catch(Exception ex) { Console.WriteLine(ex.ToString()); } Console.ReadKey(); } } }
1) If you want to monitor a specific service instance then the instance must be running when you go to add the counters to the graph.2) When the service instance stops running the graph will freeze (i.e. stop capturing data) but will restart when you restart the service.3) Setting up and configuring perfmon graphs can be time consuming so you can save them as counter logs, however you can also save a graph as html which will produce an html page with an embedded perfmon graph complete with all your counters and configurations. You can just open this page in your browser to start monitoring. This also means you can build and keep or publish a library of useful graphs.
July 15, 2007 1 Comment