<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.atalasoft.com/cs/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Rick Minerich's Development Wonderland : interop</title><link>http://www.atalasoft.com/cs/blogs/rickm/archive/tags/interop/default.aspx</link><description>Tags: interop</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>A Speedy Alternative to F# DelegateEvents</title><link>http://www.atalasoft.com/cs/blogs/rickm/archive/2010/06/04/a-speedy-alternative-to-f-delegateevents.aspx</link><pubDate>Fri, 04 Jun 2010 16:19:58 GMT</pubDate><guid isPermaLink="false">647108ca-f046-4d8d-9feb-a7fbd2049b37:20757</guid><dc:creator>RickM</dc:creator><slash:comments>4</slash:comments><comments>http://www.atalasoft.com/cs/blogs/rickm/comments/20757.aspx</comments><wfw:commentRss>http://www.atalasoft.com/cs/blogs/rickm/commentrss.aspx?PostID=20757</wfw:commentRss><wfw:comment>http://www.atalasoft.com/cs/blogs/rickm/rsscomments.aspx?PostID=20757</wfw:comment><description>&lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;DelegateEvents use DynamicInvoke under the hood and so can be slow when trigged frequently.&amp;#160; As we have an existing model which requires an event interface, this was was causing our F# implementation to be a bit slower than the C# we were comparing it to.&amp;#160; Thankfully, F# allows you to implement your own eventing via IDelegateEvent.&amp;#160; With a standard Invoke version of DelegateEvent provided by James Margetson, our implementation in F# is running at equivalent speed to C#.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The other day I was working with &lt;a href="http://www.atalasoft.com/cs/blogs/stevehawley/"&gt;Steve&lt;/a&gt; on trying to discover why a particular segment of apparently equivalent code was running ~25% slower in F# when compared to C#.&amp;#160; We broke out &lt;a href="http://www.automatedqa.com/products/aqtime/"&gt;AQTime&lt;/a&gt; and did a line by line release-mode profile.&amp;#160; The frequent triggering of a &lt;a href="http://msdn.microsoft.com/en-us/library/ee370450.aspx"&gt;DelegateEvent&lt;/a&gt; immediately jumped out as the cause.&amp;#160; &lt;/p&gt;  &lt;p&gt;Needless to say, I was a bit concerned.&amp;#160; What could be causing this slow eventing in my favorite language?&amp;#160; After a brief review of the generated IL, nothing in particular seemed fishy.&amp;#160; So, I quickly built a sample and sent it off to my favorite language team.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The contents of the F# library assembly:&lt;/strong&gt;&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:dc45fc3f-9c89-49d1-bef1-39b6ee119d05" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;white-space:nowrap;"&gt;&lt;span style="color:#0000ff;"&gt;type&lt;/span&gt; FsEventClass(num) =&lt;br&gt;     &lt;span style="color:#0000ff;"&gt;let&lt;/span&gt; event = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DelegateEvent&amp;lt;System.EventHandler&amp;lt;System.EventArgs&amp;gt;&amp;gt;()&lt;br&gt;     &lt;br&gt;     [&amp;lt;CLIEvent&amp;gt;]&lt;br&gt;     &lt;span style="color:#0000ff;"&gt;member&lt;/span&gt; this.Event = event.Publish&lt;br&gt;             &lt;br&gt;     &lt;span style="color:#0000ff;"&gt;member&lt;/span&gt; this.Run () = &lt;br&gt;         &lt;span style="color:#0000ff;"&gt;let&lt;/span&gt; args = [| this :&amp;gt; obj ; System.EventArgs.Empty :&amp;gt; obj |]&lt;br&gt;         &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; i &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; 1 .. num &lt;span style="color:#0000ff;"&gt;do&lt;/span&gt;&lt;br&gt;             args.[1] &amp;lt;- &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; System.EventArgs() :&amp;gt; obj&lt;br&gt;             event.Trigger( args )&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;And this, the C# client:&lt;/strong&gt;&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2dcf6ed5-ad9a-4cde-afbc-7e65fb9a81a1" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;white-space:nowrap;"&gt;&lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br&gt; {&lt;br&gt;     &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; iters = 1000000;&lt;br&gt; &lt;br&gt;     &lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt; fsStart = &lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;.Now;&lt;br&gt;     &lt;span style="color:#2b91af;"&gt;FSharpEventingLib&lt;/span&gt;.&lt;span style="color:#2b91af;"&gt;FsEventClass&lt;/span&gt; fs = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;FSharpEventingLib&lt;/span&gt;.&lt;span style="color:#2b91af;"&gt;FsEventClass&lt;/span&gt;(iters);&lt;br&gt;     &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; fsCalled = 0;&lt;br&gt;     fs.Event += (s, a) =&amp;gt; fsCalled++;&lt;br&gt;     fs.Run();&lt;br&gt;     &lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt; fsEnd = &lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;.Now;&lt;br&gt;     &lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt; fsTime = fsEnd - fsStart;&lt;br&gt;     System.&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;&amp;quot;F# took: {0} when called {1} times&amp;quot;&lt;/span&gt;, fsTime, fsCalled)); &lt;br&gt; }&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Finally, the program output:&lt;/strong&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;F# took: 00:00:05.6830000 when called 1000000 times&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;As it turns out, the F#’s current &lt;a href="http://msdn.microsoft.com/en-us/library/ee370450.aspx"&gt;DelegateEvent&lt;/a&gt; uses a DynamicInvoke under the hood and that can slow things down quite a bit.&amp;#160; This won’t be important in most cases as Event is implemented with a standard Invoke.&amp;#160; However, in our case we had to fit to an existing C# model and so needed to do an event trigger for each resulting scanline of an image.&lt;/p&gt;  &lt;p&gt;A big thanks to James Margetson of the F# Team for the following fast replacement for DelegateEvent.&amp;#160; Within same day I had mentioned my issue he had this solution for me.&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The new library contents:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:75d3ea67-e88d-4308-bffc-de81cd96ed5f" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background-color:#ffffff;overflow:auto;padding:2px 5px;white-space:nowrap;"&gt;&lt;span style="color:#0000ff;"&gt;type&lt;/span&gt; FastDelegateEvent() =&lt;br&gt;     &lt;span style="color:#0000ff;"&gt;let&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;mutable&lt;/span&gt; multicast : System.EventHandler = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;&lt;br&gt; &lt;br&gt;     &lt;span style="color:#0000ff;"&gt;member&lt;/span&gt; x.Trigger(sender:obj,args:System.EventArgs) =&lt;br&gt;         &lt;span style="color:#0000ff;"&gt;match&lt;/span&gt; multicast &lt;span style="color:#0000ff;"&gt;with&lt;/span&gt;&lt;br&gt;         | &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;-&amp;gt;&lt;/span&gt; ()&lt;br&gt;         | d &lt;span style="color:#0000ff;"&gt;-&amp;gt;&lt;/span&gt; d.Invoke(sender,args)   &lt;span style="color:#008000;"&gt;// DelegateEvent used: d.DynamicInvoke(args) |&amp;gt; ignore&lt;/span&gt;&lt;br&gt;  &lt;br&gt;     &lt;span style="color:#0000ff;"&gt;member&lt;/span&gt; x.Publish =&lt;br&gt;         { &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; IDelegateEvent&amp;lt;System.EventHandler&amp;gt; &lt;span style="color:#0000ff;"&gt;with&lt;/span&gt;&lt;br&gt;             &lt;span style="color:#0000ff;"&gt;member&lt;/span&gt; x.AddHandler(d) =&lt;br&gt;                 multicast &amp;lt;- System.Delegate.Combine(multicast, d) :?&amp;gt; System.EventHandler&lt;br&gt;             &lt;span style="color:#0000ff;"&gt;member&lt;/span&gt; x.RemoveHandler(d) =&lt;br&gt;                 multicast &amp;lt;- System.Delegate.Remove(multicast, d)  :?&amp;gt; System.EventHandler }&lt;br&gt; &lt;br&gt; &lt;span style="color:#0000ff;"&gt;type&lt;/span&gt; FsFastEventClass(num) =&lt;br&gt;    &lt;span style="color:#0000ff;"&gt;let&lt;/span&gt; event = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; FastDelegateEvent()&lt;br&gt; &lt;br&gt;    [&amp;lt;CLIEvent&amp;gt;]&lt;br&gt;    &lt;span style="color:#0000ff;"&gt;member&lt;/span&gt; this.Event = event.Publish&lt;br&gt; &lt;br&gt;    &lt;span style="color:#0000ff;"&gt;member&lt;/span&gt; this.Run () =&lt;br&gt;        &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; i &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; 1 .. num &lt;span style="color:#0000ff;"&gt;do&lt;/span&gt;           &lt;br&gt;            event.Trigger(this, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; System.EventArgs())&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The program output with FastDelegateEvent:&lt;/strong&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;F# took: 00:00:00.0390000 when called 1000000 times&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;This new event class completely resolved our issue.&amp;#160; With it our F# version is just as fast, if not faster, than the C# equivalent.&amp;#160; &lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.atalasoft.com/cs/blogs/rickm/archive/2010/06/04/a-speedy-alternative-to-f-delegateevents.aspx&amp;amp;;subject=A+Speedy+Alternative+to+F%23+DelegateEvents" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2010/06/04/a-speedy-alternative-to-f-delegateevents.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2010/06/04/a-speedy-alternative-to-f-delegateevents.aspx&amp;amp;;title=A+Speedy+Alternative+to+F%23+DelegateEvents" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2010/06/04/a-speedy-alternative-to-f-delegateevents.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2010/06/04/a-speedy-alternative-to-f-delegateevents.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2010/06/04/a-speedy-alternative-to-f-delegateevents.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2010/06/04/a-speedy-alternative-to-f-delegateevents.aspx&amp;amp;title=A+Speedy+Alternative+to+F%23+DelegateEvents" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2010/06/04/a-speedy-alternative-to-f-delegateevents.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2010/06/04/a-speedy-alternative-to-f-delegateevents.aspx&amp;amp;;title=A+Speedy+Alternative+to+F%23+DelegateEvents" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2010/06/04/a-speedy-alternative-to-f-delegateevents.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://www.atalasoft.com/cs/blogs/rickm/archive/2010/06/04/a-speedy-alternative-to-f-delegateevents.aspx&amp;amp;;title=A+Speedy+Alternative+to+F%23+DelegateEvents&amp;amp;;top=1" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2010/06/04/a-speedy-alternative-to-f-delegateevents.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.atalasoft.com/cs/aggbug.aspx?PostID=20757" width="1" height="1"&gt;</description><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/delegates/default.aspx">delegates</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/fsharp/default.aspx">fsharp</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/interop/default.aspx">interop</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/DelegateEvent/default.aspx">DelegateEvent</category></item><item><title>F# Discoveries This Week 12/21/2009</title><link>http://www.atalasoft.com/cs/blogs/rickm/archive/2009/12/21/f-discoveries-this-week-12-21-2009.aspx</link><pubDate>Mon, 21 Dec 2009 17:10:31 GMT</pubDate><guid isPermaLink="false">647108ca-f046-4d8d-9feb-a7fbd2049b37:19904</guid><dc:creator>RickM</dc:creator><slash:comments>1</slash:comments><comments>http://www.atalasoft.com/cs/blogs/rickm/comments/19904.aspx</comments><wfw:commentRss>http://www.atalasoft.com/cs/blogs/rickm/commentrss.aspx?PostID=19904</wfw:commentRss><wfw:comment>http://www.atalasoft.com/cs/blogs/rickm/rsscomments.aspx?PostID=19904</wfw:comment><description>&lt;p align="left"&gt;By far the most exciting news this week was the preview release of Microsoft Research Accelerator.&amp;#160; Posts on this topic by Satnam Signh and Tomas Petricek have left the F# world buzzing.&amp;#160; This, however, is just the tip of the F# iceberg.&amp;#160; News of the F# Survival Guide’s release and a number of other exciting posts follow.&lt;/p&gt;  &lt;p align="left"&gt;&amp;#160;&lt;/p&gt;  &lt;h1 align="center"&gt;-- F# --&lt;/h1&gt;  &lt;h3&gt;&lt;a href="http://blogs.msdn.com/satnam_singh/archive/2009/12/15/gpgpu-and-x64-multicore-programming-with-accelerator-from-f.aspx"&gt;Satnam Singh demonstrates GPGPU and x64 multicore programming with Accelerator&lt;/a&gt;&lt;/h3&gt;  &lt;blockquote&gt;   &lt;p align="left"&gt;&lt;em&gt;Microsoft recently released a preview of the Accelerator V2 GPU and x64 multicore programming system on Microsoft Connect. This system provides a civilized level of abstraction for writing data-parallel programs that execute on GPUs and multicore processors. An experimental FPGA target is under development.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="left"&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://tomasp.net/blog/accelerator-intro.aspx"&gt;Tomas Petricek explores Microsoft Research Accelerator&lt;/a&gt;&lt;/h3&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;The project used Microsoft Research Accelerator, which is a C# library for developing array-based computations and executing them on a GPU. […] In this article, we'll look at the simplest way of using Accelerator from F#. Accelerator provides a managed interface that can be naturally used from both C# and F#.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="left"&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://www.ctocorner.com/fsharp/book/"&gt;The F# Survival Guide – a Free eBook&lt;/a&gt;&lt;/h3&gt;  &lt;blockquote&gt;   &lt;p&gt;Welcome to the F# Survivial Guide by John Puopolo with Sandy Squires. We wrote this book to introduce mainstream developers to the world of functional programming through the lens of F#, Microsoft's first fully-supported multi-paradigm language.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="left"&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://weblogs.asp.net/podwysocki/archive/2009/12/14/going-hybrid-implementing-a-shopping-cart-in-f.aspx"&gt;Matthew Podwysocki builds a Shopping Cart in F#&lt;/a&gt;&lt;/h3&gt;  &lt;blockquote&gt;   &lt;p align="left"&gt;&lt;em&gt;Where functional programming has an immediate impact and probably the largest is programming in the small.&amp;#160; Here, we can focus on such things as immutable values, higher order functions, recursion, pattern matching and others come into play.&amp;#160; When we’re talking about mixing paradigms, object oriented programming has a larger effect on programming in the medium where we’re organizing our code and can some times offer a more elegant solution than a functional programming one.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="left"&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://lorgonblog.spaces.live.com/Blog/cns!701679AD17B6D310!1767.entry"&gt;Brian McNamara explores IObserver and IObservable&lt;/a&gt;&lt;/h3&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;At core, IObservable is just about two new small interfaces, IObservable&amp;lt;T&amp;gt; and IObserver&amp;lt;T&amp;gt;, being added to .Net 4.0.&amp;#160; We’ll come to the details of those interfaces shortly.&amp;#160; What is exciting and useful about IObservable is that these interfaces admit very nice programming models, including LINQ (e.g. for C#) and the Observable module (for F#), that provide useful combinators for transforming and using event streams.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="left"&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://www.navision-blog.de/2009/11/23/mapping-the-reactive-framework-rx-operators-for-f/"&gt;Steffen Forkmann maps the Reactive Framework operators to F#&lt;/a&gt;&lt;/h3&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;The “Reactive Extensions for .NET (Rx)” comes with lot’s of operators for using IObservable&amp;lt;T&amp;gt;. This code mimics the signature of the default F# sequence combinators and allows to use observables like sequences. It is a similar approach like Matthews Podwysocki’s blog post about mapping the IParallelEnumerable.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://strangelights.com/blog/archive/2009/12/20/1650.aspx"&gt;Robert Pickering introduces FunctionalNHibernate&lt;/a&gt;&lt;/h3&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;It’s already fairly well documented that F# doesn’t play too well with NHibernate and Fluent NHibernate, although you can make it play a littler nice with a bit of effort. However there are a few fundamental problems with this approach.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://bistrofs.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=37460"&gt;Bistro FSharp Extensions 0.9.5.0 is released&lt;/a&gt;&lt;/h3&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;The new release drastically improves the project's interaction with the inference capabilities of F#. A majority of controllers can now be written without the need for discriminated union annotations, or let bindings for naming. &lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Julien Ortin continues his series on Purely Functional Data Structures with a &lt;a href="http://lepensemoi.free.fr/index.php/2009/12/17/splay-heap"&gt;Splay heap&lt;/a&gt;, a &lt;a href="http://lepensemoi.free.fr/index.php/2009/12/17/double-ended-queue"&gt;double-ended queue&lt;/a&gt; and a &lt;a href="http://lepensemoi.free.fr/index.php/2009/12/17/pairing-heap"&gt;Pairing heap&lt;/a&gt;.&lt;/h3&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;This post describes the F# implementation of the &amp;lt;insert data structure here&amp;gt; from Chris Okasaki’s “Purely functional data structures”.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="left"&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://blogs.msdn.com/jaredpar/archive/2009/12/15/making-f-type-inference-friendly-for-c.aspx"&gt;Jared Parsons makes F# type inference friendly to C#&lt;/a&gt;&lt;/h3&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;When working with the exposed core Vim engine API, I’ve found a number of generated F# constructs which are not easily accessible from C#.&amp;#160; The problem stems from the manner in which native F# types are exposed.&amp;#160; Many of them are generic and&amp;#160; lack type inference friendly helper methods that force awkward usage patterns in C#.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="left"&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://www.russiantequila.com/wordpress/?p=99"&gt;Alex Pedenko discusses code compression with F# and MVC&lt;/a&gt;&lt;/h3&gt;  &lt;blockquote&gt;   &lt;p align="left"&gt;&lt;em&gt;While the underlying concepts are the same, a recent stint with Django (which is a strong influence in the Bistro framework) reminded me of how little work you have to do in python to get going with a controller, and that bistro and the fs extensions still have some catching up to do on the brevity front.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="left"&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://mdavey.wordpress.com/2009/12/21/thoughts-on-f-within-a-single-dealer-platform-sdp/"&gt;Matt Davey muses over F# within a Single Dealer Platform&lt;/a&gt;&lt;/h3&gt;  &lt;blockquote&gt;   &lt;p align="left"&gt;&lt;em&gt;I’ve been thinking about F# for a while and its use within finance. A number of banks have been looked at F# from an analytical viewpoint – obvious, and hence boring.&amp;#160; What is more interesting it how F# possible elevates the building of a Single Dealer Platform (SDP).&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="left"&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;&lt;a href="http://www.markhneedham.com/blog/2009/12/20/f-word-count-using-a-dictionary/"&gt;Mark Needham does Word Count using a Dictionary&lt;/a&gt;&lt;/h3&gt;  &lt;blockquote&gt;   &lt;p align="left"&gt;&lt;em&gt;Having spent some time unsuccessfully trying to make &lt;/em&gt;&lt;em&gt;my F# attempt at the word count problem&lt;/em&gt;&lt;em&gt; work I decided to follow the lead of the other examples I've read and make use of a Dictionary to keep count of the words.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="left"&gt;&amp;#160;&lt;/p&gt;  &lt;h1 align="center"&gt;-- Misc Others --&lt;/h1&gt;  &lt;h3&gt;&lt;a href="http://functionalpx.ning.com/"&gt;Functional Programming eXchange – a Ning network for FP&lt;/a&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;a href="http://blog.plover.com/prog/burritos.html"&gt;Mark Dominus on why Monads are like burritos&lt;/a&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;a href="http://patryshev.com/monad/m-intro.html"&gt;Crash Monad Tutorial&lt;/a&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;a href="http://stuartsierra.com/2009/12/14/objects-are-not-adts"&gt;Stuart Sierra on why Objects are not Abstract Data Types&lt;/a&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;a href="http://www.cs.yale.edu/homes/perlis-alan/quotes.html"&gt;Perlisms - “Epigrams in Programming” by Alan J. Perlis&lt;/a&gt;&lt;/h3&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.atalasoft.com/cs/blogs/rickm/archive/2009/12/21/f-discoveries-this-week-12-21-2009.aspx&amp;amp;;subject=F%23+Discoveries+This+Week+12%2f21%2f2009" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/12/21/f-discoveries-this-week-12-21-2009.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/12/21/f-discoveries-this-week-12-21-2009.aspx&amp;amp;;title=F%23+Discoveries+This+Week+12%2f21%2f2009" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/12/21/f-discoveries-this-week-12-21-2009.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/12/21/f-discoveries-this-week-12-21-2009.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/12/21/f-discoveries-this-week-12-21-2009.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/12/21/f-discoveries-this-week-12-21-2009.aspx&amp;amp;title=F%23+Discoveries+This+Week+12%2f21%2f2009" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/12/21/f-discoveries-this-week-12-21-2009.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/12/21/f-discoveries-this-week-12-21-2009.aspx&amp;amp;;title=F%23+Discoveries+This+Week+12%2f21%2f2009" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/12/21/f-discoveries-this-week-12-21-2009.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/12/21/f-discoveries-this-week-12-21-2009.aspx&amp;amp;;title=F%23+Discoveries+This+Week+12%2f21%2f2009&amp;amp;;top=1" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/12/21/f-discoveries-this-week-12-21-2009.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.atalasoft.com/cs/aggbug.aspx?PostID=19904" width="1" height="1"&gt;</description><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/fsharp/default.aspx">fsharp</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/roundup/default.aspx">roundup</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/functional+programming/default.aspx">functional programming</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/type+inference/default.aspx">type inference</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/data+structures/default.aspx">data structures</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/interop/default.aspx">interop</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/monads/default.aspx">monads</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/Rx/default.aspx">Rx</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/Accelerator/default.aspx">Accelerator</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/ebook/default.aspx">ebook</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/sdp/default.aspx">sdp</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/GPGPU/default.aspx">GPGPU</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/mvc/default.aspx">mvc</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/IObserver/default.aspx">IObserver</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/Bistro/default.aspx">Bistro</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/shopping+cart/default.aspx">shopping cart</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/IObservable/default.aspx">IObservable</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/manycore/default.aspx">manycore</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/FunctionalNHibernate/default.aspx">FunctionalNHibernate</category></item><item><title>Image Processing in F#: From Image File to Array</title><link>http://www.atalasoft.com/cs/blogs/rickm/archive/2009/09/03/getting-started-with-image-processing-in-f-loading-image-data-into-an-array.aspx</link><pubDate>Thu, 03 Sep 2009 18:09:37 GMT</pubDate><guid isPermaLink="false">647108ca-f046-4d8d-9feb-a7fbd2049b37:19262</guid><dc:creator>RickM</dc:creator><slash:comments>6</slash:comments><comments>http://www.atalasoft.com/cs/blogs/rickm/comments/19262.aspx</comments><wfw:commentRss>http://www.atalasoft.com/cs/blogs/rickm/commentrss.aspx?PostID=19262</wfw:commentRss><wfw:comment>http://www.atalasoft.com/cs/blogs/rickm/rsscomments.aspx?PostID=19262</wfw:comment><description>&lt;p&gt;F# has fantastic array manipulation functionality.&amp;#160; To leverage this functionality for some very elegant image processing, it is first necessary to to convert image files into a byte arrays.&amp;#160; Unfortunately, this process is not as simple as one might hope.&amp;#160; &lt;/p&gt;  &lt;p&gt;It’s a dark path of missing documentation, incorrect code samples and some ugly .NET interop.&amp;#160; With all of the other difficulties involved, I want to otherwise keep things simple and so will make the following assumptions:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The image file will be properly handled by .NET’s image codecs (it’s known to have some issues with Tiffs in particular) &lt;/li&gt;    &lt;li&gt;The Image format is 24 bits per pixel BGR &lt;/li&gt;    &lt;li&gt;The end user will handle exceptions &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;By far the most difficult things in writing this small sample was that it seemed every BitmapData implementation I ran into was completely broken.&amp;#160; In fact, this was the case for even the &lt;a href="http://msdn.microsoft.com/en-us/library/system.drawing.imaging.bitmapdata.aspx"&gt;.NET Framework SDK sample code&lt;/a&gt;.&amp;#160; For each example I tried the following two tests succeeded:&lt;/p&gt;  &lt;div style="font-family:courier new;background:white;color:black;font-size:10pt;"&gt;   &lt;p style="margin:0px;"&gt;[&amp;lt;Fact&amp;gt;]&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;member&lt;/span&gt; x.first_matches_GetPixel() =&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; pixel = bmp24Bgr.GetPixel(0,0)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; Assert.Equal( pixel.B, array24Bgr.[0] )&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; Assert.Equal( pixel.G, array24Bgr.[1] )&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; Assert.Equal( pixel.R, array24Bgr.[2] )&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;[&amp;lt;Fact&amp;gt;]&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;member&lt;/span&gt; x.last_on_first_scanline_matches_GetPixel() =&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; pixel = bmp24Bgr.GetPixel( bmp24Bgr.Width - 1 , 0 )&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; offset = (bmp24Bgr.Width - 1) * 3 &lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; Assert.Equal( pixel.B, array24Bgr.[offset] )&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; Assert.Equal( pixel.G, array24Bgr.[offset + 1] )&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; Assert.Equal( pixel.R, array24Bgr.[offset + 2] )&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Unfortunately, the following two tests would fail:&lt;/p&gt;  &lt;div style="font-family:courier new;background:white;color:black;font-size:10pt;"&gt;   &lt;p style="margin:0px;"&gt;[&amp;lt;Fact&amp;gt;]&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;member&lt;/span&gt; x.first_on_last_scanline_matches_GetPixel() =&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; pixel = bmp24Bgr.GetPixel( 0 , bmp24Bgr.Height - 1 )&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; offset = bmp24Bgr.Width * (bmp24Bgr.Height - 1) * 3&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; Assert.Equal( pixel.B, array24Bgr.[offset] )&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; Assert.Equal( pixel.G, array24Bgr.[offset + 1] )&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; Assert.Equal( pixel.R, array24Bgr.[offset + 2] )&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;[&amp;lt;Fact&amp;gt;]&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;member&lt;/span&gt; x.last_matches_GetPixel() =&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; pixel = bmp24Bgr.GetPixel( bmp24Bgr.Width - 1, &lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; bmp24Bgr.Height - 1 )&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; offset = (bmp24Bgr.Width * bmp24Bgr.Height * 3) - 3&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; Assert.Equal( pixel.B, array24Bgr.[offset ] )&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; Assert.Equal( pixel.G, array24Bgr.[offset + 1] )&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; Assert.Equal( pixel.R, array24Bgr.[offset + 2] )&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;On closer inspection it seemed something was turning everything after the first scanline into garbage.&lt;/p&gt;  &lt;p&gt;Well, it turns out that each scanline in BitmapData’s allocated memory block can have some padding on the end.&amp;#160; This mean’s you can’t simply block-copy the memory into your array as is done in so many examples.&amp;#160; Instead, it is necessary to iterate over each scanline and copy only up to the padding.&amp;#160; A fact missing from everywhere but &lt;a href="http://msdn.microsoft.com/en-us/library/system.drawing.imaging.bitmapdata.stride.aspx"&gt;a small corner of the .NET Framework BitmapData documentation&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;A big thanks to Bob Powell for &lt;a href="http://www.bobpowell.net/lockingbits.htm"&gt;his article on exactly how the BitmapData class works&lt;/a&gt;.&amp;#160; Once I saw his diagram, I knew exactly what was going on and reworked my code to Marshal the data out of each scanline separately, minus the padding.&lt;/p&gt;  &lt;div style="font-family:courier new;background:white;color:black;font-size:10pt;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;open&lt;/span&gt; System.Drawing&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;open&lt;/span&gt; System.Drawing.Imaging&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;open&lt;/span&gt; System.Runtime.InteropServices&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;let&lt;/span&gt; getBytesFromBitmap (bytesPerPixel: int) (bmp: Bitmap) =&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; imgRect = &lt;span style="color:blue;"&gt;new&lt;/span&gt; Rectangle(0, 0, bmp.Width, bmp.Height)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; bmpBits = bmp.LockBits(imgRect, ImageLockMode.ReadOnly,&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; bmp.PixelFormat)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; &lt;span style="color:blue;"&gt;try&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; pixelBytes = bmp.Height * bmp.Width * bytesPerPixel&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; byteArray: byte[] = Array.zeroCreate pixelBytes&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; scanlineBytes = bmp.Width * bytesPerPixel &lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; stride: nativeint = nativeint bmpBits.Stride&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;for&lt;/span&gt; i &lt;span style="color:blue;"&gt;in&lt;/span&gt; [ 0 .. bmp.Height - 1 ] &lt;span style="color:blue;"&gt;do&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; bmpOffset = stride * nativeint i&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;let&lt;/span&gt; arrayOffset = scanlineBytes * int i&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Marshal.Copy( bmpBits.Scan0 + bmpOffset, byteArray, &lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; arrayOffset, scanlineBytes)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; byteArray&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160; &lt;span style="color:blue;"&gt;finally&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; bmp.UnlockBits( bmpBits ) &lt;/p&gt; &lt;/div&gt;  &lt;p&gt;This code is not as pretty or efficient as it might be, but at least it works and is fairly safe.&amp;#160; I’d love to clean this up and so I encourage you to leave critiques and/or example code in the comments section. &lt;/p&gt;  &lt;p&gt;Also, I’ve made my &lt;a href="http://www.atalasoft.com/cs/files/folders/19263/download.aspx"&gt;Visual Studio 2008 solution containing the above code and a few small extras&lt;/a&gt; available.&amp;#160; Let me say again that any comments or critiques are welcome.&amp;#160; I hope that in posting this I’ve saved you the some of the pain I had in writing it.&lt;/p&gt;  &lt;p&gt;Ninja Edit:&amp;#160; The idea of this function exiting with still locked bits was really bothering me and so I put everything after LockBits into a try-finally. &lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.atalasoft.com/cs/blogs/rickm/archive/2009/09/03/getting-started-with-image-processing-in-f-loading-image-data-into-an-array.aspx&amp;amp;;subject=Image+Processing+in+F%23%3a+From+Image+File+to+Array" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/09/03/getting-started-with-image-processing-in-f-loading-image-data-into-an-array.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/09/03/getting-started-with-image-processing-in-f-loading-image-data-into-an-array.aspx&amp;amp;;title=Image+Processing+in+F%23%3a+From+Image+File+to+Array" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/09/03/getting-started-with-image-processing-in-f-loading-image-data-into-an-array.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/09/03/getting-started-with-image-processing-in-f-loading-image-data-into-an-array.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/09/03/getting-started-with-image-processing-in-f-loading-image-data-into-an-array.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/09/03/getting-started-with-image-processing-in-f-loading-image-data-into-an-array.aspx&amp;amp;title=Image+Processing+in+F%23%3a+From+Image+File+to+Array" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/09/03/getting-started-with-image-processing-in-f-loading-image-data-into-an-array.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/09/03/getting-started-with-image-processing-in-f-loading-image-data-into-an-array.aspx&amp;amp;;title=Image+Processing+in+F%23%3a+From+Image+File+to+Array" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/09/03/getting-started-with-image-processing-in-f-loading-image-data-into-an-array.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/09/03/getting-started-with-image-processing-in-f-loading-image-data-into-an-array.aspx&amp;amp;;title=Image+Processing+in+F%23%3a+From+Image+File+to+Array&amp;amp;;top=1" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/09/03/getting-started-with-image-processing-in-f-loading-image-data-into-an-array.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.atalasoft.com/cs/aggbug.aspx?PostID=19262" width="1" height="1"&gt;</description><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/memory/default.aspx">memory</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/fsharp/default.aspx">fsharp</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/xUnit.NET/default.aspx">xUnit.NET</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/image+processing/default.aspx">image processing</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/interop/default.aspx">interop</category></item></channel></rss>