annotate Implab/Components/LazyAndWeak.cs @ 187:dd4a3590f9c6 ref20160224

Reworked cancelation handling, if the cancel handler isn't specified the OperationCanceledException will be handled by the error handler Any unhandled OperationCanceledException will cause the promise cancelation
author cin
date Tue, 19 Apr 2016 17:35:20 +0300
parents 76e8f2ba12b8
children 3a6e18c432be
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
178
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
1 using System;
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
2 using System.Threading;
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
3
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
4 namespace Implab.Components {
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
5 /// <summary>
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
6 /// Creates an instace on-demand and allows it to be garbage collected.
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
7 /// </summary>
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
8 /// <remarks>
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
9 /// Usefull when dealing with memory-intensive objects which are frequently used.
182
76e8f2ba12b8 pretty print DFA, the minimization is still buggy
cin
parents: 180
diff changeset
10 /// This class is similar to <see cref="ObjectPool{T}"/> except it is a singleton.
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
11 /// </remarks>
178
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
12 public class LazyAndWeak<T> where T : class {
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
13
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
14 readonly Func<T> m_factory;
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
15 readonly object m_lock;
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
16 WeakReference m_reference;
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
17
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
18
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
19 public LazyAndWeak(Func<T> factory, bool useLock) {
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
20 Safe.ArgumentNotNull(factory, "factory");
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
21 m_factory = factory;
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
22 m_lock = useLock ? new object() : null;
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
23 }
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
24
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
25 public LazyAndWeak(Func<T> factory) : this(factory, false) {
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
26 }
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
27
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
28 public T Value {
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
29 get {
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
30 while (true) {
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
31 var weak = m_reference;
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
32 T value;
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
33 if (weak != null) {
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
34 value = weak.Target as T;
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
35 if (value != null)
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
36 return value;
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
37 }
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
38
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
39 if (m_lock == null) {
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
40 value = m_factory();
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
41
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
42 if (Interlocked.CompareExchange(ref m_reference, new WeakReference(value), weak) == weak)
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
43 return value;
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
44 } else {
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
45 lock (m_lock) {
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
46 // double check
182
76e8f2ba12b8 pretty print DFA, the minimization is still buggy
cin
parents: 180
diff changeset
47 weak = m_reference;
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
48 if (weak != null) {
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
49 value = weak.Target as T;
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
50 if (value != null)
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
51 return value;
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
52 }
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
53 // we are safe to write
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
54 value = m_factory();
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
55 m_reference = new WeakReference(value);
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
56 return value;
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
57 }
178
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
58 }
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
59 }
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
60 }
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
61 }
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
62 }
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
63 }
d5c5db0335ee working on JSON parser
cin
parents:
diff changeset
64