How can I prevent objects created in a loop from being released at the end of that iteration of the loop - scope

If I'm creating an object and I want it to only last for the current code block, after which it will be destroyed (or at least marked for destruction) automatically, I can use the scope keyword:
using System;
class Program
{
public void Program()
{
let basicString = String("Basic String");
for (let i = 0 ; i < 4 ; i++)
{
let modifiedString = scope String(s);
if (i%2 == 0)
{
modifiedString.ToUpper();
}
else
{
modifiedString.ToLower();
}
Console.WriteLine(modifiedString);
// modifiedString is marked for destruction
}
}
}
But, if I need the object to remain until after the block, such as for the whole method or for a block outside of the one it was created, how can I specify that scope? For instance, how can I ensure that the strings exist in the second loop below?
using System;
using System.Collections.Generic;
class Program
{
public void Program()
{
let basicString = String("Basic String");
let modifiedStringList = scope List<String>();
for (let i = 0 ; i < 4 ; i++)
{
let modifiedString = scope String(s);
if (i%2 == 0)
{
modifiedString.ToUpper();
}
else
{
modifiedString.ToLower();
}
modifiedStringList.Append(modifiedString);
Console.WriteLine(modifiedString);
// somehow prevent modifiedString from being marked for destruction
}
modifiedStringList.RemoveAt(1);
for (let s in modifiedStringList)
{
Console.WriteLine(s);
}
// allow all of the modifiedString to be marked for destruction here
}
}

You can use scope:: to not let the variable be marked for destruction for the entire method:
using System;
using System.Collections.Generic;
class Program
{
public void Program()
{
let basicString = String("Basic String");
let modifiedStringList = scope List<String>();
for (let i = 0 ; i < 4 ; i++)
{
// modifiedString won't be destroyed until after Program() exits.
let modifiedString = scope:: String(s);
if (i%2 == 0)
{
modifiedString.ToUpper();
}
else
{
modifiedString.ToLower();
}
modifiedStringList.Append(modifiedString);
Console.WriteLine(modifiedString);
}
modifiedStringList.RemoveAt(1);
for (let s in modifiedStringList)
{
Console.WriteLine(s);
}
}
}
If you need to specify an arbitrary scope between the method and the current block, you can use a named block with BlockName: { ... } and use scope:BlockName:
using System;
using System.Collections.Generic;
class Program
{
public void Program()
{
for (let repeat=0; repeat<10; repeat++)
RepeatBlock:
{
let basicString = String("Basic String");
let modifiedStringList = scope List<String>();
for (let i = 0 ; i < 4 ; i++)
{
// modifiedString won't be destroyed until after
// the block named RepeatBlock block exits.
let modifiedString = scope:RepeatBlock String(s);
if (i%2 == 0)
{
modifiedString.ToUpper();
}
else
{
modifiedString.ToLower();
}
modifiedStringList.Append(modifiedString);
Console.WriteLine(modifiedString);
}
modifiedStringList.RemoveAt(1);
for (let s in modifiedStringList)
{
Console.WriteLine(s);
}
}
}
}

Related

Using functions as map keys in Haxe

I want to use functions as keys in a Map like this:
var timers : Map<Void->Void, snow.api.Timer>;
But Haxe won't compile:
Abstract Map has no #:to function that accepts IMap<Void -> Void, snow.api.Timer>
Is there a way to do this ?
It's easy to write a custom implementation:
import haxe.Constraints;
class FunctionMap<K:Function,V> implements IMap<K,V> {
private var _keys : Array<K>;
private var _values : Array<V>;
public function new () {
_keys = [];
_values = [];
}
public function get(k:K):Null<V> {
var keyIndex = index(k);
if (keyIndex < 0) {
return null;
} else {
return _values[keyIndex];
}
}
public function set(k:K, v:V):Void {
var keyIndex = index(k);
if (keyIndex < 0) {
_keys.push(k);
_values.push(v);
} else {
_values[keyIndex] = v;
}
}
public function exists(k:K):Bool {
return index(k) >= 0;
}
public function remove(k:K):Bool {
var keyIndex = index(k);
if (keyIndex < 0) {
return false;
} else {
_keys.splice(keyIndex, 1);
_values.splice(keyIndex, 1);
return true;
}
}
public function keys():Iterator<K> {
return _keys.iterator();
}
public function iterator():Iterator<V> {
return _values
.iterator();
}
public function toString():String {
var s = new StringBuf();
s.add("{");
for( i in 0..._keys.length ) {
s.add('<function>');
s.add(" => ");
s.add(Std.string(_values[i]));
if( i < _keys.length - 1 )
s.add(", ");
}
s.add("}");
return s.toString();
}
private function index(key:K) : Int {
for (i in 0..._keys.length) {
if (Reflect.compareMethods(key, _keys[i])) {
return i;
}
}
return -1;
}}
http://try.haxe.org/#DdF31
I just tried this in try.haxe.org, and the compiler doesn't seem to like it, so I'm guessing the answer is "no."
You could get around this with some cleverness:
class Test {
static function main() {
var map:Map<VoidVoid,String>;
map = new Map<VoidVoid,String>();
var thing = {func:foo};
map.set(thing,"bar");
trace(map.get({func:foo})); //fails
trace(map.get(thing)); //succeeds;
}
static function foo():Void
{
}
}
typedef VoidVoid = {
var func:Void->Void;
}
But that's not an ideal solution because wrapping it in a typedef like that will make it fail if it's not the exact same instance, even if the value inside is the same.
I also tried making a Map<Dynamic,String> since you can stuff function references in those, but that didn't work either.
At this point I should ask, what problem are you trying to solve this way? Perhaps it could be better solved some other way.

Dart memory leaks and garbage collection

I understand that currently Dart doesn't have an explicit way to remove objects from memory and that objects that are no longer referenced anywhere are removed automatically.
Yet I've been running some benchmarking. Here's the code:
import 'dart:html';
import 'dart:async';
var components = [];
var times_to_run = 10;
class MockComponent {
Element element = new Element.html('<table></table>');
remove() {
element.remove();
element = null;
}
}
createAndRemoveComponents(t) {
var n = 50000; // number of objects to create and delete in this run
print("***Run #${times_to_run}");
print("creating $n objects...");
for(var i=0; i < n; i++) {
components.add(new MockComponent());
}
print("...done");
print("removing $n objects...");
while(components.length > 0) {
components.removeAt(0).remove();
}
print("...done");
times_to_run -= 1;
if(times_to_run <= 0) {
components = null;
t.cancel();
}
}
void main() {
new Timer.periodic(const Duration(seconds: 10), createAndRemoveComponents);
}
I made a video of this code running, so please take a look and see for yourself that memory actually leaks: http://www.youtube.com/watch?v=uVD8Npvc9vQ

Trying to handle thread pool in a class

I'm trying to handle thread pool in a class.
below is my code.
#include <Windows.h>
class ClassA
{
public : // user API
ClassA()
{
}
~ClassA()
{
}
public : //my muiti-thread func
void init()
{
//*************************************
// multithread Initialization
//*************************************
pool = NULL;
cleanupgroup = NULL;
rollback = 0;
bool bRet = false;
pool = CreateThreadpool(NULL);
if(NULL == pool)
{
goto cleanPool;
}
rollback = 1;
SetThreadpoolThreadMaximum(pool, 5);
bRet = SetThreadpoolThreadMinimum(pool, 10);
if (FALSE == bRet) {
goto cleanPool;
}
cleanupgroup = CreateThreadpoolCleanupGroup();
if (NULL == cleanupgroup) {
goto cleanPool;
}
rollback = 2;
SetThreadpoolCallbackPool(&CallBackEnviron, pool);
SetThreadpoolCallbackCleanupGroup(&CallBackEnviron,
cleanupgroup,
NULL);
return ;
cleanPool:
switch (rollback)
{
case 2:
// Clean up the cleanup group.
CloseThreadpoolCleanupGroup(cleanupgroup);
case 1:
// Clean up the pool.
CloseThreadpool(pool);
default:
break;
}
return ;
}
void foo()
{
PTP_WORK work = NULL;
work = CreateThreadpoolWork(ClassA::_delegate,
NULL,
&CallBackEnviron);
}
static void __stdcall _delegate(PTP_CALLBACK_INSTANCE Instance, PVOID Parameter, PTP_WORK Work)
{
//some code
}
PTP_POOL pool;
UINT rollback;
TP_CALLBACK_ENVIRON CallBackEnviron;
PTP_CLEANUP_GROUP cleanupgroup;
};
int main()
{
ClassA a;
a.init();
a.foo();
}
If you make a project and execute this code, it gets unhandled execption...
I have no clue why...
I think the exception is caused by an uninitialized structure CallBackEnviron. The documentation states that this structure must be initialized by InitializeThreadpoolEnvironment

How can I correct the error "Cross-thread operation not valid"?

This following code gives me the error below . I think I need "InvokeRequired" . But I don't understand how can I use?
error:Cross-thread operation not valid: Control 'statusBar1' accessed from a thread other than the thread it was created on.
the code :
public void CalculateGeneration(int nPopulation, int nGeneration)
{
int _previousFitness = 0;
Population TestPopulation = new Population();
for (int i = 0; i < nGeneration; i++)
{
if (_threadFlag)
break;
TestPopulation.NextGeneration();
Genome g = TestPopulation.GetHighestScoreGenome();
if (i % 100 == 0)
{
Console.WriteLine("Generation #{0}", i);
if ( ToPercent(g.CurrentFitness) != _previousFitness)
{
Console.WriteLine(g.ToString());
_gene = g;
statusBar1.Text = String.Format("Current Fitness = {0}", g.CurrentFitness.ToString("0.00"));
this.Text = String.Format("Sudoko Grid - Generation {0}", i);
Invalidate();
_previousFitness = ToPercent(g.CurrentFitness);
}
if (g.CurrentFitness > .9999)
{
Console.WriteLine("Final Solution at Generation {0}", i);
statusBar1.Text = "Finished";
Console.WriteLine(g.ToString());
break;
}
}
}
}
Easiest for reusability is to add a helper function like:
void setstatus(string txt)
{
Action set = () => statusBar1.Text = txt;
statusBar1.Invoke(set);
}
Or with the invokerequired check first:
delegate void settextdelegate(string txt);
void setstatus(string txt)
{
if (statusBar1.InvokeRequired)
statusBar1.Invoke(new settextdelegate(setstatus), txt);
else
statusBar1.Text = txt;
}
Either way the status can then be set like
setstatus("Finished");
For completeness I should add that even better would be to keep your calculating logic separated from your form and raise a status from within your calculating functionality that can be hanled by the form, but that could be completely out of scope here.

Easy way to search a string for strings

I'm trying to find the easiest way to search a string for an array of possible strings. I know the easy way to do this for characters is to use myString.IndexOfAny(charArray). But how what if I'd like to search my string for strings and not just characters? Are there any .net tricks or methods that make this easier?
Basically, I'd like to do something like this:
string myName = "rahkim";
string[] names = new string[] {"joe","bob","chris"};
if(myName.IndexOfAny(names) >= 0)
{
//success code//
}
I know there are ways to do this with loops, etc. But I was hoping for something inherent in the framework.
You should define if you want to to find equal strings or search for a matching substring. Both ways are easy pre-LINQ and with LINQ.
string myName = "rahkim";
string[] names = new string[] { "joe", "bob", "chris" };
Equal Strings, LINQ
bool contains = names.Contains(myName);
Equal Strings, Pre-LINQ
bool contains = new List<string>(name).Contains(myName);
Substrings, LINQ
bool contains = names.Any(name => name.Contains(myName));
Substring, Pre-LINQ
bool contains = false;
foreach(string name in names)
if (name.Contains(myName))
contains = true;
If anyone else found this while trying to search for a .Net method like String.IndexOfAny(String[]), this is my solution:
C#
public int IndexOfAny(string test, string[] values)
{
int first = -1;
foreach (string item in values) {
int i = test.IndexOf(item);
if (i >= 0) {
if (first > 0) {
if (i < first) {
first = i;
}
} else {
first = i;
}
}
}
return first;
}
VB
Public Function IndexOfAny(test As String, values As String()) As Integer
Dim first As Integer = -1
For Each item As String In values
Dim i As Integer = test.IndexOf(item)
If i >= 0 Then
If first > 0 Then
If i < first Then
first = i
End If
Else
first = i
End If
End If
Next
Return first
End Function
You can do a LastIndexOfAny(String[]) by just switching the
i < first
to
i > first
You can (also) use the static IndexOf method of the Array class:
bool hasName = Array.IndexOf(names, myName) > -1;
int IndexOfAny(String[] rgs) would indeed be nice but it's nominally an O(n^2) operation. If, in your application, the set of strings rgs is large and always the same, the most efficient approach is to load them into a trie data structure once, and then use the trie repeatedly to search for them within the unknown strings given at runtime.
Here is the relevant code, adapted from a C# trie source I found on the web, attributed to "Kerry D. Wong." In my version, each string in the trie has a "payload" of generic type TValue. To use this trie to simply search for substrings, the payload could always be set to true, as illustrated with simple_trie.
The other thing I changed here is that this trie automatically adapts allow for storage of arbitrary Unicode strings. The array at each node—which characterizes a trie—adjusts its base and length to accomodate the range of Unicode characters which need to be stored at that node. This allows for case-sensitive matching, for example.
The C# 3.0 initialization syntax is handy for this trie, but enabling it requires a dummy implementation of IEnumerable in order to compile. The CLR doesn't seem to call GetEnumerator() and I suggest that you don't try to enumerate with its result either.
using System;
using System.Collections.Generic;
using System.Linq; // only used in Main()
class Program
{
// trie with payload of type <String>
static Trie<String> value_trie = new Trie<String>
{
{ "rabbit", "cute" },
{ "giraffe", "tall" },
{ "ape", "smart" },
{ "hippo", "large" },
};
// degenerate case of a trie without payload
static Trie<bool> simple_trie = new Trie<bool>
{
{ "rabbit", true },
{ "giraffe", true },
{ "ape", true },
{ "hippo", true },
};
static void Main(String[] args)
{
String s = "Once upon a time, a rabbit met an ape in the woods.";
// Retrieve payloads for words in the string.
//
// output:
// cute
// smart
foreach (String word in value_trie.AllSubstringValues(s))
Console.WriteLine(word);
// Simply test a string for any of the words in the trie.
// Note that the Any() operator ensures that the input is no longer
// traversed once a single result is found.
//
// output:
// True
Console.WriteLine(simple_trie.AllSubstringValues(s).Any(e=>e));
s = "Four score and seven years ago.";
// output:
// False
Console.WriteLine(simple_trie.AllSubstringValues(s).Any(e => e));
}
}
class TrieNode<TValue>
{
private TrieNode<TValue>[] nodes = null;
private TValue m_value = default(TValue);
private Char m_base;
public Char Base { get { return m_base; } }
public bool IsEnd { get { return !m_value.Equals(default(TValue)); } }
public TValue Value
{
get { return m_value; }
set { m_value = value; }
}
public IEnumerable<TrieNode<TValue>> Nodes { get { return nodes; } }
public TrieNode<TValue> this[char c]
{
get
{
if (nodes != null && m_base <= c && c < m_base + nodes.Length)
return nodes[c - m_base];
return null;
}
}
public TrieNode<TValue> AddChild(char c)
{
if (nodes == null)
{
m_base = c;
nodes = new TrieNode<TValue>[1];
}
else if (c >= m_base + nodes.Length)
{
Array.Resize(ref nodes, c - m_base + 1);
}
else if (c < m_base)
{
Char c_new = (Char)(m_base - c);
TrieNode<TValue>[] tmp = new TrieNode<TValue>[nodes.Length + c_new];
nodes.CopyTo(tmp, c_new);
m_base = c;
nodes = tmp;
}
TrieNode<TValue> node = nodes[c - m_base];
if (node == null)
{
node = new TrieNode<TValue>();
nodes[c - m_base] = node;
}
return node;
}
};
class Trie<TValue> : System.Collections.IEnumerable
{
private TrieNode<TValue> _root = new TrieNode<TValue>();
// This dummy enables C# 3.0 initialization syntax
public System.Collections.IEnumerator GetEnumerator()
{
return null;
}
public void Add(String s, TValue v)
{
TrieNode<TValue> node = _root;
foreach (Char c in s)
node = node.AddChild(c);
node.Value = v;
}
public bool Contains(String s)
{
TrieNode<TValue> node = _root;
foreach (Char c in s)
{
node = node[c];
if (node == null)
return false;
}
return node.IsEnd;
}
public TValue Find(String s_in)
{
TrieNode<TValue> node = _root;
foreach (Char c in s_in)
{
node = node[c];
if (node == null)
return default(TValue);
}
return node.Value;
}
public IEnumerable<TValue> FindAll(String s_in)
{
TrieNode<TValue> node = _root;
foreach (Char c in s_in)
{
node = node[c];
if (node == null)
break;
if (node.Value != null)
yield return node.Value;
}
}
public IEnumerable<TValue> AllSubstringValues(String s)
{
int i_cur = 0;
while (i_cur < s.Length)
{
TrieNode<TValue> node = _root;
int i = i_cur;
while (i < s.Length)
{
node = node[s[i]];
if (node == null)
break;
if (node.Value != null)
yield return node.Value;
i++;
}
i_cur++;
}
}
};
Here's the right syntax:
if(names.Contains(myName))
{
//success code//
}
if (names.Contains(myName))
{
//success code//
}

Resources