Posts Tagged ‘Programming in general’

31
Jul

Array of WaitHandles (ManualResetEvent, AutoResetEvent, …) when waiting for operations to complete …

Often, when you discover the beauty of multithreading and parallelism, you find a need to run some operations in parallel and wait for completion. Fairly common scenario. Although now, with .NET Framework 4, you can write it using Task Parallel Library‘s Parallel.Invoke, there are scenarios when you need to plug it in into some other methods/parameters, so you’ll do it yourself explicitly with threads or better to say ThreadPool.

The method I see from time to time looks basically like this:

void DoSomethingExample()
{
	int numberOfActions = 10;
	ManualResetEvent[] mres = new ManualResetEvent[numberOfActions];
	for (int i = 0; i < numberOfActions; i++)
	{
		mres[i] = new ManualResetEvent(false);
		ThreadPool.QueueUserWorkItem((o) =>
			{
				Thread.SpinWait(20000000);
				(o as ManualResetEvent).Set();
			},
			mres[i]);
	}
	ManualResetEvent.WaitAll(mres);
}

Though it’s not wrong, except the ManualResetEvents are not Disposed, it’s suboptimal. You’re wasting resources creating array of these objects.

But if you think about it, you can write it better. Better in a way for scaling, performance and memory consumption.

void DoSomethingBetter()
{
	int numberOfActions = 10;
	using (ManualResetEvent mre = new ManualResetEvent(false))
	{
		for (int i = 0; i < numberOfActions; i++)
		{
			ThreadPool.QueueUserWorkItem((o) =>
				{
					Thread.SpinWait(20000000);
					if (Interlocked.Decrement(ref numberOfActions) == 0)
						mre.Set();
				},
				null);
		}
		mre.WaitOne();
	}
}

I’m simply using one synchronization object (and using using statement ;) ), because I’m really interested in only when all tasks are done (one stuff), and decrementing the total number of tasks every time one finishes. Using Interlocked class I’m sure no race condition will occur and I’ll get the right results. After it reaches zero I’m signaling I’m done and the method can continue.

Fewer resources, atomic operations usage … better/faster results.

  • Twitter
  • Facebook
  • Share/Bookmark
23
Jul

Is ORM just about bridging the gap or are we trying to wrongly match ER world into OO world?

Recently I’ve got to think about ER world and OO world. There’s a lot of people around there who understand ER or OO world very deeply. In fact ER world is well formalized, described and has a strong mathematical background. A lot of theoretical work is behind OO as well. But what about ORMs?

Is it about the fact we understand both worlds correctly and it’s good we’re trying to bridge them using the power of machines instead of our hands and brains all over again or the exact opposite? Trying to wrongly create something that automagically does this bridging even if the bridge itself will be bloated, slow and creating ugly results?

Have you ever seen query from Entity Framework, LLBLGen Pro, Hibernate, nHibernate, …, name yours? Don’t blame the tool. I think any of them is doing great job translating the query from some king of object oriented way of expressing what I want to i.e. SQL. The problem is, that we’re not querying database, but objects mapped to database objects. Sometimes with very clever mapping. The tool then has to reason about some general transitions from objects to tables and then creating the query. Sure a room for improvement is here. But is it worth?

What other options do we have? Object databases (or post-relational)? Relational programming (probably not)? Maybe just the ORMs idea is wrong. Maybe the bridging is good, and we just need to start from the other end and do it differently. Maybe allow lower the abstraction for those who understand both worlds. And remember these worlds proved self to be very useful doing what they were designed to do. So we just need to find a way to work in both with less friction; or did we find it?

  • Twitter
  • Facebook
  • Share/Bookmark
14
Apr

Go language

I was looking at Go language presentation now.

The first stuff that took my attention was the C-like syntax. I really don’t like it. I want my language to talk to me. There’s, IMO, no reason in todays world to have identifiers and symbols from only couple of characters and using a lot of different characters from various places on keyboard.

Anyway what was interesting for me was the concept of channels, especially the mapping the to threads and attempt to effectively use system resources. The APM (Asynchronous Programming Model) and/or new Tasks both looks similar to channels – at least from the view what it’s offering, not how it’s exposed into language.

I don’t know about internals. But I’m sure, that the threading and parallelism attempts to get some reasonable programming model(s) are exponentially growing.

  • Twitter
  • Facebook
  • Share/Bookmark
6
Mar

Missing notes for new IEnumerable<string> methods

I noticed is that the documentation for some of new IEnumerable<string> methods in System.IO I wrote before is missing important parts. For example, the old method has notes about unstable sorting and about the different behavior for patterns where the extension is exactly three characters long. But the new one is missing these notes and these are quite important, in my opinion. I hope this is just because we’re in RC stage and in RTM all will be ready. Else it could cause confusion when using new methods (until you find the string[] version (or this post ;) )).

  • Twitter
  • Facebook
  • Share/Bookmark
6
Mar

IEnumerable<string> result for some methods in System.IO

The .NET Framework 4 includes some nice new methods in System.IO namespace. There’s a lot of methods on Directory class etc. returning string[]. That’s OK until you try to enumerate directory with thousands of files (for example). Then you’re waiting for complete result even is you just need couple of first item. The new EnumerateXxx methods are solving this as these are returning IEnumerable<string> (i.e. EnumerateFiles).

I’m looking forward to use these in ID3 renamer when .NET Framework 4 will be released.

  • Twitter
  • Facebook
  • Share/Bookmark
9
Jan

Directory.GetFiles moral

Oh yes. I have here another moral. And it’s not good for me, because it’s (again) described in documentation (but who reads it when there’s nice IntelliSense?). In my program ID3 renamer I have couple of custom IO operations. One of fundamental methods is for enumerating directory(ies) for all MP3 files. It’s based on Directory.GetFiles and few functions inside ID3 renamer need exact order of files. One of these functions is FreeDB search. When I was renaming files on my network share, it wasn’t finding anything. But when moving the directory to local drive everything was fine.

After some debugging I found, that the ordering of files from network share is different than from local drive. If you look to documentation you see:

The order of the returned file names is not guaranteed; use the Sort() method if a specific sort order is required.

Ahh, there’s your problem. :) Sadly enough, the ordering from local drive looks stable and it’s based on filename as expected. Thus in a lot of cases you’ll not smell that something may go wrong. But on non local drives (for me my NAS) you’ll hit this immediately.

Never mind, could be worse (my first shot was some bug in my “MP3File” class and that will be really bad, as it could break users’ files). This can be fixed easily.

  • Twitter
  • Facebook
  • Share/Bookmark
29
Oct

My Timer usage and references moral

Few minutes ago I got flash of intelligence. I’m using Timer in one of my windows service running simply 24×7. And I had a bug getting wrong data on server that I was not able to reproduce locally. Same data, same code, nothing. That was pretty weird, because after roughly four days I restarted the service and it started working correctly.

I opened a debugger, started the service locally and went for some candy. Because the data should be refreshed by default every two minutes, when I came back I realized, that the refresh procedure was not run, because there was a breakpoint, but no hit. So I started looking for some info in documentation, when suddenly the note followed by recalling the knowledge came in:

As long as you are using a Timer, you must keep a reference to it. As with any managed object, a Timer is subject to garbage collection when there are no references to it. The fact that a Timer is still active does not prevent it from being collected.

Yep, I was creating the instance but I was not holding a reference to it, so in under the refresh interval it was garbage collected. : Shame on me. But. We learn by mistakes.

  • Twitter
  • Facebook
  • Share/Bookmark
1
Aug

Noviny.

Nevím, co mě to někdy popadne a vezmu si v autobuse/letadle noviny. Asi mám pocit, že bych měl číst také „klasické“ médium. Jenže po pěti minutách jsem hned naštvaný. Mám špinavé prsty. A nedá se pořádně otáčet stránky. Noviny jsou moc velké a papír je měkký.

Vím, že následujících pár dní/měsíců si zase noviny brát nebudu (a pak zase jednou jo :) ). Ale přemýšlím, jestli už finálně není čas na novou technologii pro toto médium.

A možná jsem jen profesně deformován a nejradši bych jen vše četl na nějakém elektronickém zařízení. ;)

  • Twitter
  • Facebook
  • Share/Bookmark
13
Jul

Uživatelsky přívětivé vybírání složek

Nevím, jestli je to jen můj problém/pocit, ale v standardním balíku komponent v .NETu není nic co se by se podobalo něčemu jako „shell tree“, prostě to co má Explorer v okně nalevo. Hledal jsem i před časem na různých místech, ale nic pořádného.

Právě něco jako shell tree používám v ID3 renameru a trochu se tam mixuje přístup, kdy fakticky je třeba pracovat přímo s tím co je na filesystému bez ohledu na všelijaké libraries a packages a speciální složky, na stranu druhou běžný uživatel pracuje s pojmy jako „Plocha“ a „Tento počítač“ (pokud se to jmenuje jinak, omlouvám se, nepoužívám český OS). A tohle všechno výběr komponenty jenom zesložiťuje. Nehledě na to, že XP-Vista-W7, každý systém trochu jiné figurky. To pak aby se tvůrce komponenty zbláznil, když to má transparentně pokrýt.

Přemýšlím proto o jiném přístupu k výběru složky (ID3 renamer se zaměřuje na dávkové zpracování, takže jednotlivé soubory nejsou ve většině případů pro výběr důležité). Stejně rozklikávat postupně strom nemusí být vždy nejrychlejší. Bohužel mě nic nenapadá – koukám na různé programy a nic. Je jasné, že vybraná cesta musí být viditelná, a to dobře a musí jít rychle a lehce změnit, hlavně takové ty změny „okolo“ (jedna složka před a za, …).

Neřešil někdo podobný problém? Možná chytrá cesta využití standardních dialogů … Možná něco vlastního, ale ultra jednoduchého, rychlého a účelného …

Pozn.: Drag’n’Drop samozřejmě ID3 renamer podporuje, ale domnívám se, že to není všelék – musí být i možnost změny složky, se kterou chci pracovat i přímo z programu.

  • Twitter
  • Facebook
  • Share/Bookmark
8
Jun

Rotační hyperboloid? Ale kdepak.

Minulý týden jsem byl v Liberci, kde jsem prováděl školení pro firmu INISOFT. Mimochodem skvělá parta lidí – a BabySmash, náhodou zmíněný, zaznamenal fenomenální úspěch. ;-)

Mimo to jsem měl možnost se podívat na horu Ještěd (1012m). Na vrcholu je stavba (televizní vysílač a hotel), jejíž tvar má být rotační hyperboloid. Z dálky možná, ale na místě … Některé plochy jsou prostě víc rovné než “oblé”. Podvod. :) Nicméně i tak doporučuji navštívít. Výhled je super a stavba opravdu pěkně následuje tvar terénu.

  • Twitter
  • Facebook
  • Share/Bookmark
20
May

is, as, != null

Po diskuzi v postu if, else, return jsem si uvědomil, že mám v kapse ještě jeden případ, který je podobně sporný-zajímavý. Tyto dvě konstrukce vídávám a opět v zásadě stejné – nebo ne?

Foo x = (y as Foo);
if (x != null)
{
  x...
}
else
{
  // <error>
}

resp. (samozřejmě můžeme i přiřadit do x)

if (y is Foo)
{
  (y as Foo)...
}
else
{
  // <error>
}

Osobně používam druhý způsob, opět spíše pocitově něž pro nějaký fakt (myslím, že z toho is je výsledek mého snažení lépe čitelný). A co vy? Případně máte nějaký argument proč používat jedno nebo druhé?

  • Twitter
  • Facebook
  • Share/Bookmark
14
May

if, else, return

Občas vidím ve zdrojácích funkce s konstrukcí:

if (<condition>)
{
  x = DoSomething(y);
  return x;
}
return z;

Což je víceméně to samé jako:

if (<condition>)
{
  x = DoSomething(y);
  return x;
}
else
{
  return z;
}

Osobně používám druhý zápis. Přijde mi o něco přehlednější a explicitnější. Pravděpodobně vliv Delphi/ObjectPascalu.

Je však v těchto zápisech nějaký rozdíl? Nějaký praktický aspekt, který mi uniká?

  • Twitter
  • Facebook
  • Share/Bookmark