It is so tiresome to be stupid...
It turns out that if you assign null to your variable and then use it as a reference, the program throws an exception - who would've thought about this :)
Yes, I assigned null to the active variable, not intentionally of course. If only the debugger would have pointed me in the right place....
Can you post the rest of that class or a small repro?
Below is a bigger fragment of code. The formatting is messed up though. The external code written in C# calls the GetActiveManager property in the loop, and as I mentioned at first (2 or 3 times) it seems to do what it's supposed to, but then it just blows up with the exception dialog pointing right at the beginning of the lock function. Tomorrow I will try to put together a smaller repro, but for now here it is:
type Manager (filters: Map<string, ISimpleFilter>, tags: Map<string, ITag>, templates: Map<string, ITemplate>, loader: ITemplateLoader) =
let filters = filters
let tags = tags
let templates = templates
let loader = loader
member this.Templates = templates
member this.Filters = filters
member this.Tags = tags
member private this.Loader = loader
static member private lock = new obj()
/// Retrieves the current active template manager
static member GetActiveManager =
lock (lock) (
fun () ->
match !active with
| Some v -> v :?> Manager
| None ->
let m =
new Manager(
Map<string, ISimpleFilter>([]),
Map<string, ITag>([]),
Map<string, ITemplate>([]),
new DefaultLoader())
active := Some (m :> obj)
m
)
ok, here are my observations/questions:
- what are the first 4 let-bindings for?
- I have a problem with the lock(lock) - it looks like GetActiveManager returns a "() -> Manager" is that right? Why return a function? I guess you want to write "GetActiveManger()" - but then just say "static member GetActiveManager () = ... blablabla" without the fun. Or you might want to put the lock(lock) -statement "in" the returned function - i.e. one line below the "fun() ->" (btw: you don't have to use the "(" ")" bracletes for the lock - just indent the code one more)
- I can't see where you define the active-ref maybe the problem lies with this (the debuger might point you to the lock - but the CLR is not good in debuging anonymous methods so the NullReference might lie inside the returned function instead!)
- what are the first 4 let-bindings for?
I need them to be able to define the members right below the lets
- I have a problem with the lock(lock) - it looks like GetActiveManager returns a "() -> Manager" is that right? Why return a function?
According to the compiler the return value of the GetActiveManager property is Manager, as intended. It is also confirmed by the fact that first 2 times it did give me my template manager and it did for me exactly what I needed
I guess you want to write "GetActiveManger()" - but then just say "static member GetActiveManager () = ... blablabla" without the fun. Or you might want to put the lock(lock) -statement "in" the returned function - i.e. one line below the "fun() ->" (btw: you don't have to use the "(" ")" bracletes for the lock - just indent the code one more)
- I can't see where you define the active-ref maybe the problem lies with this (the debuger might point you to the lock - but the CLR is not good in debuging anonymous methods so the NullReference might lie inside the returned function instead!)
the active-ref is defined one line up before the type definition with the following statement:
let (active: obj option ref) = ref None
- what are the first 4 let-bindings for?
I need them to be able to define the members right below the lets
No you don't :) You can use the constructor parameters directly in you code. the compiler will automatically turn them into fields for you. Deleting the four let's in your code should work in exactly the same way.
- I have a problem with the lock(lock) - it looks like GetActiveManager returns a "() -> Manager" is that right? Why return a function?
It's needed for the lock function - it takes an object and a function and then executes the function after taking the lock, and cleaning up after. Similar to the lock statement in C#, but without needing a new keyword. So this code looks correct to me.By the way, you could get rid of the casts by defining active as a Manager option ref type.
well - sorry about the lock - to my shame(?) I have to admit that I never used lock in F# before.
I thought it's just a languague construct instead of a function.
You also have "using" (that encapsulates a use expression) that's one of the really nice things about having good support for higher order functions and succintness you can much easier go from encapsulating "object" to the finer grained abstraction of control flow.
- what are the first 4 let-bindings for?
I need them to be able to define the members right below the lets
No you don't :) You can use the constructor parameters directly in you code. the compiler will automatically turn them into fields for you. Deleting the four let's in your code should work in exactly the same way.
I thougt so too, but the compiler begs to differ. When I tried to remove them it complains about the members referencing the values - or am I missing something here?
- I have a problem with the lock(lock) - it looks like GetActiveManager returns a "() -> Manager" is that right? Why return a function?
It's needed for the lock function - it takes an object and a function and then executes the function after taking the lock, and cleaning up after. Similar to the lock statement in C#, but without needing a new keyword. So this code looks correct to me.
By the way, you could get rid of the casts by defining active as a Manager option ref type.
I would like to, but this would create a circular reference between the variable and the Manager type - right?
The following compiles for me. Don't know why you can't remove the let bindings - that should work. Right onthe circular reference - the workaround I've used below is to split the type into two parts. Not stellar, but at least it has no runtime overhead. I believe mutually recursive type and let bindings will be addressed in future F# releases.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
type Manager (filters: Map<string, string>) = member this.Filters = filters static member private lock = new obj() let active: Manager option ref = ref None type Manager with /// Retrieves the current active template manager static member GetActiveManager = lock (lock) ( fun () -> match !active with | Some v -> v | None -> let m = new Manager(Map<string, string>([])) active := Some m m )
You can abstract out the Singleton code like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
module Singleton = let Create<'a> (init:unit -> 'a) = let lockObj = new obj() and active : 'a option ref = ref None fun () -> lock(lockObj) (fun () -> match !active with | Some x -> x | None -> let instance = init() active := Some instance instance) type Manager (filters: Map<string, ISimpleFilter>, tags: Map<string, ITag>, templates: Map<string, ITemplate>, loader: ITemplateLoader) = member this.Templates = templates member this.Filters = filters member this.Tags = tags member private this.Loader = loader /// Retrieves the current active template manager static member GetActiveManager = Singleton.Create (fun () -> new Manager( Map<string, ISimpleFilter>([]), Map<string, ITag>([]), Map<string, ITemplate>([]), new DefaultLoader()))
My personal oppinion on singletons are that they're a gigantic anti-pattern but if they suite your design at least this way you don't need to re-implement that logic :)
The following compiles for me. Don't know why you can't remove the let bindings - that should work. Right onthe circular reference - the workaround I've used below is to split the type into two parts. Not stellar, but at least it has no runtime overhead. I believe mutually recursive type and let bindings will be addressed in future F# releases.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20type Manager (filters: Map<string, string>) = member this.Filters = filters static member private lock = new obj() let active: Manager option ref = ref None type Manager with /// Retrieves the current active template manager static member GetActiveManager = lock (lock) ( fun () -> match !active with | Some v -> v | None -> let m = new Manager(Map<string, string>([])) active := Some m m )
I tried to remove the lets, and this time around it compiled - go figure
Topic tags
- f# × 3705
- websharper × 1897
- compiler × 286
- functional × 201
- ui next × 139
- c# × 121
- classes × 97
- web × 97
- .net × 84
- book × 84
- async × 76
- ui.next × 67
- bug × 54
- core × 49
- website × 49
- server × 45
- parallel × 43
- ui × 43
- enhancement × 41
- parsing × 41
- testing × 41
- trywebsharper × 41
- typescript × 37
- html × 35
- javascript × 35
- owin × 35
- asynchronous × 30
- monad × 28
- ocaml × 28
- tutorial × 27
- warp × 27
- haskell × 26
- sitelet × 25
- linq × 22
- workflows × 22
- wpf × 20
- fpish × 19
- introduction × 19
- silverlight × 19
- sitelets × 19
- monodevelop × 17
- rpc × 17
- suave × 17
- piglets × 16
- collections × 15
- feature request × 15
- jquery × 15
- templates × 15
- getting started × 14
- pipeline × 14
- kendoui × 13
- reactive × 12
- 4.1.0.171 × 11
- monads × 11
- opinion × 10
- 4.0.190.100-rc × 9
- deployment × 9
- fixed × 9
- formlets × 9
- in × 9
- json × 9
- plugin × 9
- proposal × 9
- scheme × 9
- solid × 9
- basics × 8
- concurrent × 8
- highcharts × 8
- how-to × 8
- python × 8
- 4.1.1.175 × 7
- complexity × 7
- documentation × 7
- visual studio × 7
- 4.1.2.178 × 6
- lisp × 6
- real-world × 6
- released in 4.0.192.103-rc × 6
- remoting × 6
- resources × 6
- scala × 6
- websharper ui.next × 6
- workshop × 6
- xaml × 6
- 4.0.193.110 × 5
- 4.2.3.236 × 5
- aspnetmvc × 5
- authentication × 5
- azure × 5
- bootstrap × 5
- conference × 5
- dsl × 5
- formlet × 5
- java × 5
- list × 5
- metaprogramming × 5
- ml × 5
- released in Zafir.4.0.188.91-beta10 × 5
- sql × 5
- visualstudio × 5
- websharper.forms × 5
- zafir × 5
- 4.0.192.106 × 4
- 4.0.195.127 × 4
- 4.1.0.38 × 4
- 4.2.1.86 × 4
- 4.2.6.118 × 4
- css × 4
- example × 4
- extensions × 4
- fsi × 4
- fsx × 4
- html5 × 4
- jqueryui × 4
- lift × 4
- reflection × 4
- remote × 4
- rest × 4
- spa × 4
- teaching × 4
- template × 4
- websocket × 4
- wontfix × 4
- 4.0.196.147 × 3
- 4.1.0.34 × 3
- 4.1.6.207 × 3
- 4.2.1.223-beta × 3
- 4.2.11.258 × 3
- 4.2.4.114 × 3
- 4.2.4.247 × 3
- 4.2.5.115 × 3
- 4.2.6.253 × 3
- 4.2.9.256 × 3
- ajax × 3
- alt.net × 3
- aml × 3
- asp.net mvc × 3
- canvas × 3
- cloudsharper × 3
- compilation × 3
- database × 3
- erlang × 3
- events × 3
- extension × 3
- file upload × 3
- forums × 3
- inline × 3
- issue × 3
- kendo × 3
- macro × 3
- mono × 3
- msbuild × 3
- mvc × 3
- pattern × 3
- piglet × 3
- released in Zafir.4.0.187.90-beta10 × 3
- svg × 3
- type provider × 3
- view × 3
- 4.1.1.64 × 2
- 4.1.5.203 × 2
- 4.1.7.232 × 2
- 4.2.10.257 × 2
- 4.2.3.111 × 2
- 4.2.5.249 × 2
- android × 2
- asp.net × 2
- beginner × 2
- blog × 2
- chart × 2
- client × 2
- client server app × 2
- clojure × 2
- computation expressions × 2
- constructor × 2
- corporate × 2
- courses × 2
- cufp × 2
- d3 × 2
- debugging × 2
- direct × 2
- discriminated union × 2
- docs × 2
- elm × 2
- endpoint × 2
- endpoints × 2
- enterprise × 2
- entity framework × 2
- event × 2
- f# interactive × 2
- fable × 2
- flowlet × 2
- formdata × 2
- forms × 2
- fsc × 2
- google maps × 2
- hosting × 2
- http × 2
- https × 2
- iis 8.0 × 2
- install × 2
- interactive × 2
- interface × 2
- iphone × 2
- iteratee × 2
- jobs × 2
- jquery mobile × 2
- keynote × 2
- lens × 2
- lenses × 2
- linux × 2
- listmodel × 2
- mac × 2
- numeric × 2
- oauth × 2
- obfuscation × 2
- offline × 2
- oop × 2
- osx × 2
- packaging × 2
- pattern matching × 2
- performance × 2
- pipelines × 2
- q&a × 2
- quotation × 2
- reference × 2
- released in Zafir.4.0.185.88-beta10 × 2
- rx × 2
- script × 2
- security × 2
- self host × 2
- seq × 2
- sockets × 2
- stm × 2
- tcp × 2
- trie × 2
- tutorials × 2
- type × 2
- url × 2
- var × 2
- websharper.charting × 2
- websharper4 × 2
- websockets × 2
- wig × 2
- xna × 2
- zh × 2
- .net interop × 1
- 2012 × 1
- 4.0.194.126 × 1
- 4.1.3.184 × 1
- 4.1.4.189 × 1
- 4.2.0.214-beta × 1
- 4.2.12.259 × 1
- 4.2.2.231-beta × 1
- 4.2.8.255 × 1
- Canvas Sample Example × 1
- DynamicStyle Animated Style × 1
- Fixed in 4.0.190.100-rc × 1
- Released in Zafir.UI.Next.4.0.169.79-beta10 × 1
- SvgDynamicAttribute × 1
- WebComponent × 1
- abstract class × 1
- accumulator × 1
- active pattern × 1
- actor × 1
- addin × 1
- agents × 1
- aggregation × 1
- agile × 1
- alter session × 1
- animation × 1
- anonymous object × 1
- apache × 1
- api × 1
- appcelerator × 1
- architecture × 1
- array × 1
- arrays × 1
- asp.net 4.5 × 1
- asp.net core × 1
- asp.net integration × 1
- asp.net mvc 4 × 1
- asp.net web api × 1
- aspnet × 1
- ast × 1
- attributes × 1
- authorization × 1
- b-tree × 1
- back button × 1
- badimageformatexception × 1
- bash script × 1
- batching × 1
- binding-vars × 1
- bistro × 1
- body × 1
- bundle × 1
- camtasia studio × 1
- cas protocol × 1
- charts × 1
- clarity × 1
- class × 1
- cli × 1
- clipboard × 1
- clojurescript × 1
- closures × 1
- cloud × 1
- cms × 1
- coding diacritics × 1
- color highlighting × 1
- color zones × 1
- combinator × 1
- combinators × 1
- compile × 1
- compile code on server × 1
- config × 1
- confirm × 1
- content × 1
- context × 1
- context.usersession × 1
- continuation-passing style × 1
- coords × 1
- cordova × 1
- cors × 1
- coursera × 1
- cross-domain × 1
- csla × 1
- current_schema × 1
- custom content × 1
- data × 1
- data grid × 1
- datetime × 1
- debug × 1
- declarative × 1
- delete × 1
- devexpress × 1
- dhtmlx × 1
- dictionary × 1
- directattribute × 1
- disqus × 1
- distance × 1
- do binding × 1
- doc elt ui.next upgrade × 1
- docker × 1
- dojo × 1
- dol × 1
- dom × 1
- domain × 1
- du × 1
- duf-101 × 1
- dynamic × 1
- eastern language × 1
- eclipse × 1
- edsl × 1
- em algorithm × 1
- emacs × 1
- emotion × 1
- enums × 1
- error × 1
- etw × 1
- euclidean × 1
- eventhandlerlist × 1
- examples × 1
- ext js × 1
- extension methods × 1
- extra × 1
- facet pattern × 1
- failed to translate × 1
- fake × 1
- fantomas × 1
- fear × 1
- float × 1
- form × 1
- form-data × 1
- forum × 1
- fp × 1
- frank × 1
- fsdoc × 1
- fsharp × 1
- fsharp.core × 1
- fsharp.powerpack × 1
- fsharpx × 1
- fsunit × 1
- function × 1
- functional style × 1
- game × 1
- games × 1
- gc × 1
- generic × 1
- geometry × 1
- getlastwin32error × 1
- getting-started × 1
- google × 1
- google.maps × 1
- grid × 1
- group × 1
- guide × 1
- hash × 1
- headers × 1
- hello world example × 1
- heroku × 1
- highchart × 1
- history × 1
- how to × 1
- html-templating × 1
- http405 × 1
- httpcontext × 1
- hubfs × 1
- i18n × 1
- ie 8 × 1
- if-doc × 1
- iis × 1
- image × 1
- images × 1
- inheritance × 1
- initialize × 1
- input × 1
- install "visual studio" × 1
- installer × 1
- int64 × 1
- interfaces × 1
- internet explorer × 1
- interop × 1
- interpreter × 1
- io × 1
- iobservable × 1
- ios × 1
- iot × 1
- ipad × 1
- isomorphic × 1
- javascript optimization × 1
- javascript semanticui resources × 1
- jquery-plugin × 1
- jquery-ui × 1
- jquery-ui-datepicker × 1
- js × 1
- kendo datasource × 1
- kendochart × 1
- kendoui compiler × 1
- knockout × 1
- l10n × 1
- learning × 1
- library × 1
- libs × 1
- license × 1
- licensing × 1
- lineserieszonescfg × 1
- local setting × 1
- localization × 1
- logging × 1
- loop × 1
- macros × 1
- mailboxprocessor × 1
- mapping × 1
- maps × 1
- markerclusterer × 1
- markup × 1
- marshal × 1
- math × 1
- mathjax × 1
- message × 1
- message passing × 1
- message-passing × 1
- meta × 1
- metro style × 1
- micro orm × 1
- minimum-requirements × 1
- mix × 1
- mobile installation × 1
- mod_mono × 1
- modal × 1
- module × 1
- mouseevent × 1
- mouseposition × 1
- multidimensional × 1
- multiline × 1
- multithreading × 1
- mysql × 1
- mysqlclient × 1
- nancy × 1
- native × 1
- nested × 1
- nested loops × 1
- node × 1
- nunit × 1
- object relation mapper × 1
- object-oriented × 1
- om × 1
- onboarding × 1
- onclick × 1
- optimization × 1
- option × 1
- orm × 1
- os x × 1
- output-path × 1
- override × 1
- paper × 1
- parameter × 1
- persistence × 1
- persistent data structure × 1
- phonegap × 1
- pola × 1
- post × 1
- powerpack × 1
- prefix tree × 1
- principle of least authority × 1
- privacy × 1
- private × 1
- profile × 1
- programming × 1
- project × 1
- project euler × 1
- projekt_feladat × 1
- protected × 1
- provider × 1
- proxy × 1
- ptvs × 1
- public × 1
- pure f# × 1
- purescript × 1
- qna × 1
- quant × 1
- query sitelet × 1
- question × 1
- quotations × 1
- range × 1
- raphael × 1
- razor × 1
- rc × 1
- reactjs × 1
- real-time × 1
- ref × 1
- region × 1
- released in 4.0.190.100-rc × 1
- reporting × 1
- responsive design × 1
- rest api × 1
- rest sitelet × 1
- restful × 1
- round table × 1
- router × 1
- routing × 1
- rpc reverseproxy × 1
- runtime × 1
- sales × 1
- sample × 1
- sampleapp × 1
- scriptcs × 1
- scripting × 1
- search × 1
- self hosted × 1
- semanticui × 1
- sequence × 1
- serialisation × 1
- service × 1
- session-state × 1
- sharepoint × 1
- signals × 1
- sitelet website × 1
- sitelet.protect × 1
- sitlets × 1
- slickgrid × 1
- source code × 1
- sqlentityconnection × 1
- ssl × 1
- standards × 1
- static content × 1
- stickynotes × 1
- streamreader × 1
- stress × 1
- strong name × 1
- structures × 1
- submitbutton × 1
- subscribe × 1
- svg example html5 websharper.ui.next × 1
- sweetalert × 1
- system.datetime × 1
- system.reflection.targetinvocationexception × 1
- table storage × 1
- targets × 1
- tdd × 1
- templates ui.next × 1
- templating × 1
- text parsing × 1
- three.js × 1
- time travel × 1
- tls × 1
- tooltip × 1
- tracing × 1
- tsunamiide × 1
- turkish × 1
- twitter-bootstrap × 1
- type erasure × 1
- type inference × 1
- type providers × 1
- type-providers × 1
- typeprovider × 1
- ui next forms × 1
- ui-next × 1
- ui.next jqueryui × 1
- ui.next charting × 1
- ui.next formlets × 1
- ui.next forms × 1
- ui.next suave visualstudio × 1
- ui.next templating × 1
- unicode × 1
- unittest client × 1
- upload × 1
- usersession × 1
- validation × 1
- vb × 1
- vb.net × 1
- vector × 1
- view.map × 1
- visal studio × 1
- visual f# × 1
- visual studio 11 × 1
- visual studio 2012 × 1
- visual studio shell × 1
- vs2017 compiler zafir × 1
- vsix × 1
- web api × 1
- web-scraping × 1
- webapi × 1
- webcomponents × 1
- webforms × 1
- webgl × 1
- webrtc × 1
- webshaper × 1
- websharper async × 1
- websharper codemirror × 1
- websharper f# google × 1
- websharper forms × 1
- websharper reactive × 1
- websharper rpc × 1
- websharper sitelets routing × 1
- websharper warp × 1
- websharper-interface-generator × 1
- websharper.chartsjs × 1
- websharper.com × 1
- websharper.exe × 1
- websharper.owin × 1
- websharper.ui.next × 1
- websharper.ui.next jquery × 1
- websockets iis × 1
- why-websharper × 1
- windows 7 × 1
- windows 8 × 1
- windows-phone × 1
- winrt × 1
- www.grabbitmedia.com × 1
- xamarin × 1
- xml × 1
- yeoman × 1
- yield × 1
- zafir beta × 1
- zafir websharper4 × 1
- zarovizsga × 1
![]() |
Copyright (c) 2011-2012 IntelliFactory. All rights reserved. Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy |
Built with WebSharper |
I have a singleton object and I want to define a property on the object delivering a reference to my singleton. This property accessor has to be synchronzied because it can be accessed from multiple threads. So here is how I am trying to define it:
static member GetActiveManager = lock (TemplateManager.lockobj) ( fun () -> match !active with | Some v -> Some (v :?> TemplateManager) | None -> None )
The lockobj is another static member on the same object. In my single threaded test this expression works fine 2 or 3 times and then it throws a null reference exception with the call stack pointing at the lock function. Any idea what I am doing wrong?