internal static void CreateMutableResourceVaultTheCorrectWay() { var sbVault = MutableResourceVault <StringBuilder> .CreateAtomicMutableResourceVault(() => new StringBuilder(), TimeSpan.FromMilliseconds(250)); Console.WriteLine(@$ "We just created a [{sbVault}] in the correct way -- " + @"only the mutable resource vault will ever see the StringBuilder it constructs."); }
internal static void CreateMutableResourceVaultTheIncorrectWay() { var sbVault = MutableResourceVault <StringBuilder> .CreateAtomicMutableResourceVault(() => BadPreExistingStringBuilder, TimeSpan.FromMilliseconds(250)); Console.WriteLine( $@"We just created an [{sbVault}] in a very, very bad way. " + @"The vault now protects a resource that pre-existed the vault." + @$ " A change to {nameof(BadPreExistingStringBuilder)} is not thread-safe " + @"and will propagate to the vault's protected resource!"); }
internal static void CreateMoreComplicatedMutableResourceTheCorrectWay() { var sbVault = MutableResourceVault <PrettyBadMoreComplexExample> .CreateAtomicMutableResourceVault(() => { var sbOne = new StringBuilder(); var sbTwo = new StringBuilder(); return(new PrettyBadMoreComplexExample(sbOne, sbTwo)); }, TimeSpan.FromMilliseconds(250)); Console.WriteLine(@$ "I just created a more complicated {sbVault} in the correct way." + @" Neither the PrettyBadMoreComplexExample nor any of its subobjects are " + @"accessible outside the mutable resource vault."); }
internal static void CreateMoreComplicatedMutableResourceInASlightlySubtleIncorrectWay( StringBuilder shouldBeSecond) { var sbVault = MutableResourceVault <PrettyBadMoreComplexExample> .CreateAtomicMutableResourceVault(() => { var sbOne = new StringBuilder(); //VERY BAD! Any change to ShouldBeSecond (which is accessible outside the vault) //is not thread-safe //and will propagate to the value in the vault! return(new PrettyBadMoreComplexExample(sbOne, shouldBeSecond)); }, TimeSpan.FromMilliseconds(250)); Console.WriteLine(@$ "I just created a {sbVault} in a very unsafe but subtle way. " + @$ "If anyone changes the object referred to by {nameof(shouldBeSecond)}," + @"It will propagate in an unsafe way to the value protected by the vault."); }
static void TestIllegalNotVsProtectable() { StringBuilder [] sb = { new StringBuilder("Hi"), new StringBuilder("Mon"), }; DateTime[] datesAndTimes = GenDateTime(10); ImmutableArray <StringBuilder> immutSb = sb.ToImmutableArray(); ImmutableArray <DateTime> immut = datesAndTimes.ToImmutableArray(); var wrapper = VsArrayWrapper <DateTime> .CreateArrayWrapper(datesAndTimes); // var wrapper2 = VsArrayWrapper<StringBuilder>.CreateArrayWrapper(sb); //NOT OK -- is "considered" vault safe but isn't allowed as a protected resource //BasicVault<VsArrayWrapper<DateTime>> v = new BasicVault<VsArrayWrapper<DateTime>>(wrapper); //Ok -- ImmutableArray<DateTime> is vault safe //BasicVault<ImmutableArray<DateTime>> v = new BasicVault<ImmutableArray<DateTime>>(immut); //ok resource is not vault safe but mutresv doesnt require it MutableResourceVault <ImmutableArray <StringBuilder> > b = MutableResourceVault <ImmutableArray <StringBuilder> > .CreateAtomicMutableResourceVault( () => immutSb.ToImmutableArray(), TimeSpan.FromSeconds(2));
public static void ShowWrapperUsage() { Console.WriteLine("Begin showing wrapper usage."); MutableResourceVault <List <int> > vault = MutableResourceVault <List <int> > .CreateAtomicMutableResourceVault(() => new List <int> { 1, 2, 3, 4 }, TimeSpan.FromMilliseconds(250)); ImmutableArray <int> finalContents; { using var lck = vault.SpinLock(); List <int> addUs = new List <int> { 5, 6, 7, 8 }; //ERROR DotNetVault_VsDelegateCapture cannot capute non-vault //safe param addUs, of type List, not vault-safe //lck.ExecuteAction((ref List<int> res) => res.AddRange(addUs)); //Ok reference is to thin readonly wrapper around list of vault-safe type. //state cannot be commingled in the delegate. VsListWrapper <int> wrapper = VsListWrapper <int> .FromList(addUs); lck.ExecuteAction((ref List <int> res) => res.AddRange(wrapper)); finalContents = lck.ExecuteQuery((in List <int> res) => res.ToImmutableArray()); } Console.WriteLine("Printing final contents: "); StringBuilder sb = new StringBuilder("{"); foreach (var i in finalContents) { sb.Append($"{i}, "); } if (sb[^ 1] == ' ' && sb[^ 2] == ',')
private static MutableResourceVault <StringBuilder> CreateExampleVault() => MutableResourceVault <StringBuilder> .CreateAtomicMutableResourceVault(() => new StringBuilder("Hello, world!"), TimeSpan.FromMilliseconds(250));
internal static MutableResourceVault <StringBuilder> CreateMutableResourceVault() => MutableResourceVault <StringBuilder> .CreateAtomicMutableResourceVault(() => new StringBuilder(), TimeSpan.FromMilliseconds(100));