Saturday, April 12, 2014

Safe-casting Pointers

You cannot safe-cast a pointer. This will fail:

ptr as TProject

You can only cast pointers the unsafe way:

TProject(ptr)

That is, unless you use this neat trick:

TObject(ptr) as TProject

This will also catch programming errors, specifically a pointer that doesn’t point to an object.

Monday, April 07, 2014

Short tips: PNGImage

If you have problems processing PNG images because you are using DevExpress components, add this to the beginning of your program’s uses list:

  dxGDIPlusClasses,
Vcl.Imaging.PNGImage,

DevExpress registers PNG handler with doesn’t behave exactly the same as Delphi’s built-in TGraphics descendants. With this addition, PNGImage.RegisterFileFormat will be called after dxGDIPlusClasses.RegisterFileFormat and will overwrite DevExpress’ PNG handler.

Thursday, March 13, 2014

IOmniPipeline termination bug

There was a nasty race condition in the IOmniPipeline termination code which could result in access violations. It has been fixed in the SVN so please update to the latest version if you are using Parallel.Pipeline, Parallel.BackgroundWorker, or Parallel.ForkJoin.

Great thanks go to Dean from DeNovo Software who narrowed down the problem and make sure I can repeat it on my machine.

Friday, February 28, 2014

RAD Studio XE5, C++, iOS etc … in Slovenia

This Tuesday (March 4th) Embarcadero and Marand are organizing a RAD Studio XE5 presentation in Ljubljana. We’ll be showing great features that were implemented in RAD Studio in the past few years – from 64-bit Windows compilation, Unicode support and styling to multiplatform development, LiveBindings and FireDAC. For the first time in Slovenia we’ll be presenting the new REST library and C++ support for iOS.

Presentation will be given in Slovenian language. Register here.

Friday, February 07, 2014

Worst. Interface. Ever.

As seen on Blogger:

image

I have just written a reply and clicked “Sign out”. For the third time since the Google changed the Blogger UI!

I don’t care that the “Publish” button is highlighted. “Sign out” is just placed in perfect position to click on when you are typing a response.

Fix this, Google!

Thursday, January 09, 2014

OmniThreadLibrary 3.03b – Small version change, big update!

Yesterday I noticed a big nasty bug in the OmniThreadLibrary which was present in for a long long time. If a thread priority was not explicitly specified (by calling SetPriority OTL function or SetThreadPriority Windows API), a thread was started with idle priority (instead of normal).

How comes nobody has noticed that? Well, it looks like the Windows thread scheduler is really great and nicely schedules threads even in such case. Still, this is something that has to be fixed and I have immediately released new version.

If you’re using OTL, please download the newest version or update from the SVN.

New features

  • Added SetPriority function to the IOmniTaskConfig.
  • Added indexed writers ([number] and [name]) to both TOmniValue and TOmniValueContainer.

Bug fixes

  • Thread priority is set correctly (to 'normal') if it is not explicitly specified.
  • Corrected swapped content of 'Schedule Observed'/'Schedule Unobserved' methods in the 11_ThreadPool test (tnx to [semele]).
  • Locked<T>.Free can be called if Locked<T> owns its Value.

Friday, December 13, 2013

It’s that time of the year …

… when you can get “Parallel Programming with OmniThreadLibraryand three “High-Level Multithreading with OmniThreadLibrary” for a reduced price!

Go to https://leanpub.com/omnithreadlibrary and buy the “The Book + Webinars” package for mere $29.99!

By the way, now you can buy a site-wide license – buy the book and give it to anybody in your organisation for mere $250! Plus you get all three webinars in the deal.

Monday, December 09, 2013

Smart Mobile Studio 2.0 beta 1

I know we promised it for November so here it is – Smart Mobile Studio 2.0 beta 1, released on November 39th ;)

I know some were waiting anxiously for this release so joke aside – we are sorry that we couldn’t release it in November but you know how it goes – there is always one more showstopper problem :( We know that this beta is not yet perfect (and we’ll release another one before the product is finalized) but as we do want your feedback we have exposed it for the public consumption.

A list of changes since the last released version is available here.

In case you were not actively following Smart since the last release, I would like to recommend few interesting articles on our site:

And remember – Smart targets everything from microcontrollers (Espruino) to mobile devices (in-browser, PhoneGap, Cordova), desktop (in-browser) to servers (NodeJS).

Saturday, December 07, 2013

SapMM

This is a guest post, written by Anton Alisov, software PM and developer from Ivanovo city, Russia.

I’m posting it here because I want to increase visibility of this new memory manager which featured quite well on my recent test (guest posted at Eric’s blog). I’m perfectly aware that my test was superficial and I intend to do a better test with more memory managers in the following weeks.

Arnaud Buchez already posted a overview of the memory manager on his blog.

And now I’ll give word to my colleague Anton.


We were waiting for the robust and scalable memory manager for Delphi for the long time. Our best choice - FastMM - did not scale well under multithreaded use in memory intensive applications. Memory manager with
a new design was required. We have tested many scalable managers such as TopMM, ScaleMM and other. Some of them are quite robust, but not supported currently by its developers (TopMM), some are not yet ready
for production. So, we decided to develop our own memory manager to have more control over it. We believe, one doesn't have to be big to be efficient. Meet a new player - SapMM - Simple As Possible Memory Manager.

SapMM is robust, production quality memory manager, developed by software guru Alexei Nedoria from Ivanovo city, Russia. SapMM was designed for use in memory intensive multithreaded applications with the
scalability in the first place. In single threaded use SapMM is only a bit (up to 40% on certain scenarios) slower than FastMM (on some scenarios SapMM is faster than FastMM even in single threaded use), but
the real power of SapMM shows in multihreaded applications. SapMM scales very well and in a vast majority of scenarios is much faster than FastMM in multithreaded use.

SapMM is used in production 24/7 system since June 2013. Currently SapMM was well tested only with Delphi XE and XE3, small code changes may be required in order to use it with other versions of Delphi. Currently SapMM supports only 32-bit mode and cannot be used in 64-bit applications. You can grab SapMM sources and do some tests yourself: https://code.google.com/p/sapmm/

Monday, November 25, 2013

Embarcadero Academy – Android Programming

Next Tuesday (December 3rd) we’ll continue the Embarcadero Academy line of presentations for Slovenian developers. This time I’ll cover programming for Android devices in Delphi XE5.

Register here.

Predavanje bo v slovenskem jeziku.

Sunday, November 17, 2013

ITDevCon 2013 Slides, Code and Photos

ITDevCon 2013 has finished and as always it was a beautiful (but wearying) experience. I’m still trying to pull myself together.

My session slides and code are now available on this blog – just click on the Presentations link on the right.

Some snapshots from the conference (take with the crappy camera on the Sony Xperia P phone):

01_
Opening session

02_
Last preparations …

03_
Smart Mobile Studio everywhere

04_
Three fifths of the Smart Mobile Studio team

05_
Christian during the “LLVM” presentation

06_
Stefan Glienke talking about Spring4D

07_
The Spring4D session was packed

08_
Christian preparing for the “Microcontrollers and Pascal” session

Wednesday, October 23, 2013

ITDevCon 2013–Lots of hard choices

Yellow – sessions I’d like to attend.

Green – sessions I really want to attend.

Red – sessions I have to attend.

Can somebody please invent a time machine before November 14th?

image

Monday, October 21, 2013

OmniThreadLibrary 3.03a

OmniThreadLibrary 3.03a has just been released. This is purely a bugfix release which fixes ugly problem in the ForEach abstraction. If the code has called ForEach with empty input set (for example, ForEach(0, –1)), the program would block infinitely.

OTL 3.03a is available via SVN or as a ZIP archive.

ITDevCon 2013

image

The ITDevCon conference is almost there (register while you still can!). As four times before, the organizer has invited an impressive list of speakers which will be giving 19 presentations (if I counted correctly), divided in three parallel tracks over two days. The conference will occur on 14th and 15th in the beautiful city of Verona.

On the first day of the conference I’ll be presenting two Delphi-related sessions. In the Using attributes and RTTI to automate programming tasks talk, I’ll introduce a concept of attributes in Delphi and present few different practical uses for this interesting but underused language concept.

In my second session of the day, Continuous Integration, delivery and deployment, I’ll talk about continuous integration and its cousins, continuous delivery and continuous deployment. In the session I’ll present few different software tools that support those concepts and I’ll also speak about practical experiences with continuous integration in the field.

On the second day of the conference, both my sessions will revolve around the Smart Mobile Studio. [BTW, four SMS developers will be visiting – and presenting at the conference. This year’s ITDevCon is a great place to discuss JavaScript programming with Pascal!] In the Smart Mobile Studio today session I'll present new release of Smart Mobile Studio 2.0, which should be released soon after the ITDevCon. SMS 2.0 will support new targets (Node.JS, Espruino, Web Workers), contain new components and libraries (grid, new game framework) and new data connectors (DataSnap) so I’ll have problems showing everything new inside the one hour time frame.

In my second session of the day, From Zero to Hero in 60 minutes, I'll try to write a very simple client/server mobile application in one hour. The client side will run in a browser, the server side in Node.JS, and both will be written in Pascal without adding a single line of JavaScript. Participants will be welcome to test the application while it is being developed.

I hope I’ll see you in Verona so we can talk about Delphi, Pascal, and everything related and unrelated!

Tuesday, October 15, 2013

OmniThreadLibrary 3.03–quick fix

Yesterday’s 3.03 version was somehow corrupted (in a way that it doesn’t compile). I have no idea what I did wrong as I did recompile test apps before committing and they did compile. Anyhow, if you’re one of the first 85 downloaders, please download the corrected version or implement a very simple fix. In the OtlParallel unit on the line 1663 a class prefix is missing. Just type it in and everything will work.

class procedure Parallel.ApplyConfig(const taskConfig: IOmniTaskConfig; ...

The management apologizes for the inconvenience. ;)

EDIT 2013-10-16: It has been brought to my attention that both the original 3.03 and yesterday's fix were missing the XE5 packages. This has been now fixed. You can download missing packages from here.

Monday, October 14, 2013

OmniThreadLibrary 3.03

OmniThreadLibrary 3.03 has just been released. It is available via SVN or as a ZIP archive.

What is OmniThreadLibrary?

OmniThreadLibrary is simple to use threading library for Delphi. It's main "selling" points (besides the price, of course are power, simplicity, and openess. With just few lines of code, you can set up multiple threads, send messages between them, process Windows messages and more. OmniThreadLibrary doesn't limit you in any way - if it is not powerfull enough for you, you can ignore any part of its "smartness" and replace it with your own code. If you don't like working with threads - no problem! You can use high-level primitives like parallel for, futures and pipelines to introduce parallelism into your application.

OmniThreadLibrary is an open source project. It lives in the Google Code and is licensed under the BSD license.

At the moment, OmniThreadLibrary supports Delphi 2007, 2009, 2010, XE, XE2, XE3, XE4, and XE5 on the Win32 and Win64 platforms. Currently, there are no plans to support older Delphi compilers and .NET. XE2+
support is limited to Windows targets. Firemonkey is currently not supported.

Where can I get more information?

Home page: http://www.omnithreadlibrary.com/
Web discussion forum: http://otl.17slon.com/forum/
Downloads: http://code.google.com/p/omnithreadlibrary/downloads/list
Issue tracker: http://code.google.com/p/omnithreadlibrary/issues/list
SVN checkout instructions: http://code.google.com/p/omnithreadlibrary/source/checkout
Author's blog: http://thedelphigeek.com
Author's home page: http://www.glagolite.si/delphi/
Documentation wiki: http://otl.17slon.com/book/
Documentation book: http://http://leanpub.com/omnithreadlibrary

Changes since version 3.02

New features
Bug fixes
  • Fixed XE2/XE3 package compilation.
  • TOmniBaseBounded(Queue|Stack) internally aligns allocated memory to required CAS granularity (8 bytes on 32-bit platforms, 16 bytes on 64-bit platforms) (tnx to [Alexander Alexeev]).
  • TOmniBaseBoundedQueue's ring buffers are internally aligned to 2*SizeOf(pointer) (tnx to [Alex Egorov]).
  • Prevent memory leak if (Queue|Stack).Initialize is called more than once (tnx to [h.hasenack]).
  • Fixed memory leaks in `forEach output` and `checkVat` examples(tnx to [Steve Maughan]).
  • Fixed TOmniTaskGroup.TerminateAll.
  • Simple pipeline stage handles exceptions in the executor function.
  • Compiles when 'Typed @ operator' is enabled (tnx to [arioch]).
  • Removed optimization which caused ForEach to behave differently on uniprocessor computers.
New demos
  • 54_LockManager: Demonstrates the new lock manager (IOmniLockManager<K>).

Friday, October 11, 2013

TStreamAdapter.Seek – Apology

Sometimes you write a blog post that you wish you wouldn’t. Maybe you don’t, but I certainly did. Yesterday I wrote about TStreamAdapter.Seek Broken For Large Files I completely incorrectly stated that “the bug was not fixed in XE4/XE5”.

The reason for my mistake was that although I verified the problem in the XE2, I didn’t write any test code for it (we already had a failing application so I didn’t have to – or so I thought) and I only checked the RTL for changes. I found out that the TStreamAdapter.Seek didn’t change from XE2 to XE4/5 and assumed the worst.

Well, the good guys at Embarcadero did fix the problem in the meantime – but in a different place. They have added a new Seek overload to the TStream class and this new Seek (which is implemented as an inline function) acts as an intermediary between the TStreamAdapter and the correct TStream.Seek method. This solution is much better than our quick fix as it also fixes all other code in the world which mistakenly calls the wrong Seek overload.

function Seek(Offset: Longint; Origin: Word): Longint; overload; virtual;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; virtual
;
function Seek(const Offset: Int64; Origin: Word): Int64; overload; deprecated; inline
;

function TStream.Seek(const Offset: Int64; Origin: Word):
Int64;
begin
Result := Seek(Offset,
TSeekOrigin(Origin));
end
;

Thanks to the Arioch’s prompt in the original post I did write a test code today and when I finally tested it on the XE5, it run just fine! Imagine my shame. :(


What have I learned today? That looking at the source code is not enough, especially if you want to complain. Always write a test case (and then run it!).


I deeply apology to Embarcadero programmers (especially to the guy who fixed the original error) and to you, my readers.


And now, if you’ll excuse me, I’ll pull a cover over my head and gently weep.

TStreamAdapter.Seek Test

This is simple test code which tests TStreamAdapter.Seek functionality and doesn’t require creating 4+GB files on the disk. A fix is also included.

program SeekTest;

{$APPTYPE CONSOLE}

{$R *.res}

uses
Windows, SysUtils, Classes,
ActiveX;

type
TTestStream = class
(TStream)
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
overload; override
;
end
;

var
GSeekOffset:
int64;

(* quick fix
type
TStreamAdapter = class(Classes.TStreamAdapter)
public
function Seek(dlibMove: Int64; dwOrigin: Integer;
out libNewPosition: Int64): HRESULT; override; stdcall;
end;

function TStreamAdapter.Seek(dlibMove: Int64; dwOrigin: Integer;
out libNewPosition: Int64): HRESULT;
var
NewPos: LargeInt;
begin
try
if (dwOrigin < STREAM_SEEK_SET) or (dwOrigin > STREAM_SEEK_END) then
begin
Result := STG_E_INVALIDFUNCTION;
Exit;
end;
NewPos := Stream.Seek(dlibMove, TSeekOrigin(dwOrigin));
if @libNewPosition <> nil then
libNewPosition := NewPos;
Result := S_OK;
except
Result := STG_E_INVALIDPOINTER;
end;
end;
*)

function TTestStream.Seek(const Offset: Int64; Origin: TSeekOrigin):
Int64;
begin
GSeekOffset :=
Offset;
Result :=
Offset;
end
;

var
ts:
TTestStream;
sa:
TStreamAdapter;
np:
int64;

begin
ts :=
TTestStream.Create;
sa := TStreamAdapter.Create(ts,
soOwned);
sa.Seek($123456789, soFromBeginning,
np);
sa.Free;
if GSeekOffset = $123456789
then
Writeln('Seek is OK'
)
else
Writeln('Seek is broken'
);
Readln;
end
.

Thursday, October 10, 2013

TStreamAdapter.Seek Broken For Large Files

EDIT I was completely wrong in my analysis and this bug was indeed fixed in XE4. I'm leaving the original (slightly edited) post below - firstly to remind myself to thoroughly test everything before posting and secondly to help some poor programmer who will run into the same problem with Delphi XE, XE2, XE3 ... in the future.


Yesterday a colleague informed me that he added a workaround for a VCL bug (which we confirmed to exist in XE2, XE4 and XE5) to our codebase and asked me if I could “inform the authorities”, i.e. enter it into QualityCentral. Imagine my surprise when I not only found the bug already entered but marked as fixed!

The problematic code is posted below, problem marked with a yellow color as it is hard to spot.

function TStreamAdapter.Seek(dlibMove: Largeint; dwOrigin: Longint;
out libNewPosition: Largeint): HResult;
var
NewPos: LargeInt;
begin
try
if (dwOrigin < STREAM_SEEK_SET) or (dwOrigin > STREAM_SEEK_END) then
begin
Result := STG_E_INVALIDFUNCTION;
Exit;
end;
NewPos := FStream.Seek(dlibMove, dwOrigin);
if @libNewPosition <> nil then libNewPosition := NewPos;
Result := S_OK;
except
Result := STG_E_INVALIDPOINTER;
end;
end;

TStream implements two Seek methods (below). The former is here for backwards compatibility and allows only seeking in 32-bit-addressable (i.e. smaller than 4 GB) files. The latter supports files larger than 4 GB.

function Seek(Offset: Longint; Origin: Word): Longint; overload; virtual;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; virtual
;

If you Ctrl+Click on ‘Seek’ in the TStreamAdapter.Seek implementation, IDE will jump to the latter Seek – which is incorrect as in reality the former (32-bit) seek is called. That makes the problem harder to spot.


Embarcadero people – can somebody please reopen the original bug report? This is something that surely needs to be fixed.


Our temporary (we’ll see for how many future Delphi versions) fix is the same as in the QC #105985 – make a copy of the TStreamAdapter.Seek and cast the dwOrigin parameter into TSeekOrigin enumeration so that the correct TStream.Seek method is called.

type
TStreamAdapter = class
(Classes.TStreamAdapter)
public
function Seek(dlibMove: Int64; dwOrigin: Integer; out libNewPosition: Int64): HRESULT; override; stdcall
;
end
;

function TStreamAdapter.Seek(dlibMove: Int64; dwOrigin: Integer; out libNewPosition: Int64):
HRESULT;
var
NewPos:
LargeInt;
begin
try
if (dwOrigin < STREAM_SEEK_SET) or (dwOrigin > STREAM_SEEK_END)
then
begin
Result :=
STG_E_INVALIDFUNCTION;
Exit;
end
;
NewPos := Stream.Seek(dlibMove,
TSeekOrigin(dwOrigin));
if @libNewPosition <> nil
then
libNewPosition :=
NewPos;
Result :=
S_OK;
except
Result :=
STG_E_INVALIDPOINTER;
end
;
end
;

Wednesday, September 18, 2013

XE5 Is Well Accepted

This picture was taken today in Ljubljana before the XE5 presentation (which, thank you for asking, went quite fine, with only two glitches of which one was a human – that is, mine – error).

About 65 people attended, which is a great improvement from the XE4 launch, and quite a few of them have expressed an interest in buying the Delphi/Android combo.

01_

The all present subtext was, however, that “Embarcadero should now slow down the development and FIX THE BUGS!” I cannot disagree with that – since the XE2, the Delphi has become increasingly less and less reliably. The time has come for a big spring cleanup.

Wednesday, September 11, 2013

XE5 and USB Drivers

If your XE5 installation doesn’t want to recognize attached Android phone when Windows see it perfectly well (and you have done all the groundwork including putting the phone into USB Debugging mode), check if you have installed USB drivers that support adb – the android debugger. Typically, the drivers that are installed automatically by Windows won’t work with the adb.

This page links to correct drivers for various phone manufacturers.

This StackOverflow topic may help you in case of hard-to-resolve problems.

And, of course, read the official documentation on debugging on Android devices first!

Friday, September 06, 2013

The Delphi Language is Lagging Behind

While I love the way Delphi is expanding to multiple platforms (but please, guys, stop the horses once in a while and fix some bugs!), I think the Delphi language could use a facelift. In particular, I like what Eric is doing with the DWS and I absolutely enjoy coding in Smart Mobile Studio where I could use the full power of Eric’s improvements to the language.

I absolutely love DWS’ lambda statement. Delphi’s approach to anonymous methods is so damn long-winded (even for us Pascal programmers who love to type) that lots of programmers reject it just because of the unwieldy syntax. In DWS, however, I can use

var repeater := TW3EventRepeater.Create(lambda (Sender) => MyFunction, 5000);

or

ResizeChildren(FClientArea.Height, [TAlign.Top, TAlign.Bottom],
lambda (layout) => layout.GetConfig.GetHeight,
lambda (layout, value) layout.GetConfig.Height(value) end);

Much shorter. More readable.


Also useful are properties with anonymous storage. If my property only exposes a field and doesn’t use getter or setter, I can shorten the code by 50% by not defining the field at all. Instead of

type
TMyClass = class
private
FData: integer;
public
property Data: integer read FData write FData;
end;

I can write

type
TMyClass = class
public
property Data: integer;
end;

Another nice feature are property expressions – a way to write anonymous getters and setters.

type
TToDoListTemplate=class(TW3form)
public
property Task: string read (W3lblTask.Caption) write (W3lblTask.Caption);
property Detail: string read (W3lblDet.Caption) write (W3lblDet.Caption);
end;

These are incredible time saver. If I redo this the Delphi way, I end up with a much longer code.

type
TToDoListTemplate=class(TW3form)
private
function GetDetail: string;
function GetTask: string;
procedure SetDetail(value: string);
procedure SetTask(value: string);
public
property Task: string read GetTask write SetTask;
property Detail: string read GetDetail write SetDetail;
end;






function TToDoListTemplate.GetDetail: string;
begin
Result := W3lblDet.Caption;
end;


function TToDoListTemplate.GetTask: string;
begin
Result := W3lblTask.Caption;
end;


procedure TToDoListTemplate.SetDetail(value: string);
begin
W3lblDet.Caption := value;
end;


procedure TToDoListTemplate.SetTask(value: string);
begin
W3lblTask.Caption := value;
end;

I also love type inference and in-line variable declaration which allow me to write code like this:


var item := ActionList.Items[ActionList.Add] as TLBItem;
item.Header := header;
item.Text := text;


or


for var item in ActionList.Items do


When I have to write a multiline string constant, multiline strings come handy.


writeln("Hello
World");


Even better – DWS will ignore leading common indentation if string is introduced with #” (or #’).


writeln(#"
    Hello
    World");


And last (but definitely not least), DWS implements a true conditional operator.


s := if a = 0 then 0 else 1/a;

Thursday, September 05, 2013

Delphi XE5 – Slovenian Launch

I’ll be presenting the full XE5 development powers – developing for Windows, OS X, iOS and Android in Ljubljana, on September 18th.

Register here!

Monday, August 12, 2013

OmniThreadLibrary Documentation–Low-level Multithreading

A new chapter (59 pages) on low-level multithreading has been added to the Parallel Programming with OmniThreadLibrary book. The book now has 264 pages.

Only one large part is now missing – a chapter on various supporting data structures (TOmniValue, Environment hierarchy …) and units (OtlHooks). I will write it next, then I’ll close up with the Introduction to MultiThreading.

If you have already bought the book, you should have received an email notification with download link by now. In case it got lost, please go to http://leanpub.com, log in and go to your Dashboard where you’ll be able to download the book.

If you want to buy the book, just click here. You’ll be taken to the public page for the book where you’ll also be able to download the sample PDF, which has now two new sections – an introductory part on low-level OTL programming and a section on lock-free collections.

Thursday, July 04, 2013

High-Level Multithreading webinars–recordings

All three webinars are now available for download! For a mere $10 you’ll get a hour-long presentation of OmniThreadLibrary tools that will greatly simplify your multithreaded programming.

Part I: Introduction, Async/Await, Future, Join

Part II: Parallel Task, Background Worker, Fork/Join

Part III: For Each, Pipeline

A bundle of all three webinars is also available for mere $25: High-Level Multithreading.

To download code samples and presentations, visit the OmniThreadLibrary webinars page.

Saturday, June 29, 2013

High-Level Multithreading Part III, repeat

If you have missed the webinar on Thursday or if you couldn’t reconnect after the very unfortunate dropout, you can join the retransmission on Tuesday 2nd at 10.00 AM PDT / 19.00 CET. I’ll be going through the complete webinar for the purpose of recording so you can drop in conveniently late ;)
Registration link: https://www2.gotomeeting.com/register/535786066

Thursday, June 27, 2013

State of the Software: BAD

Internet is a fragile, fragile thing. Listeners to my webinars know that.

Last time we got disconnected because of connection problems on my side.

Today, the webinar just ended. Listeners and presenters, we all just got the message that the organizer has ended the webinar. Well, he didn’t. He even restarted it and immediately got disconnected again with the same message :(

Sadly, we will not be able to finish the webinar today. I’m very very sorry for that.

Tuesday, June 25, 2013

Webinars–Reschedule and Recording

The code and slides for the Part I of the High-Level Multithreading webinar is available now at www.omnithreadlibrary.com/webinars.htm, as is the link to the downloadable video, which is being sold on Gumroad for $10.

Part II of the webinar was rescheduled for July 3rd. It will be transmitted at 15:30 CET / 9:30 EDT / 6:30 PDT / 23:30 AEST. Register here. Even if you were registered for the interrupted webinar, you'll have to register again.

If you are not yet registered for Part III yet (this Thursday at the same hour as rescheduled Part II), you can register here. Please keep in mind that all parts are independent – even if you missed part I, parts II and III will be completely understandable.

Monday, June 24, 2013

Webinar II Fail :(

I would like to apologize to everybody participating today for the technical difficulties. We had some storms in the area earlier before and they have affected internet connections more than I expected.

After a choppy first third of the webinar I completely lost connection and dropped out and now I cannot reconnect to the GoToWebinar at all. Sorry :(

We will repeat this webinar soon. I’ll post the new date here as soon as I know it.

Thursday, June 13, 2013

Register for the OmniThreadLibrary Webinars!

Everything is set up and now you can register by clicking on the links below.

Each part will last about an hour and will start at 15:30 CET / 9:30 EDT / 6:30 PDT / 23:30 AEST.

Webinars will be available for the download. They will cost $10 each and bundles with reduced price will be available. Online webinars are free to attend.

Wednesday, June 12, 2013

DataSnap/FireDAC in Ljubljana

FireDAC/DataSnap was well visited in well accepted (and I also had a great time preparing it). Big thanks to everybody for attending!
2013-06-12 09.05.24
Materials (in Slovenian language) are available here.

Tuesday, June 11, 2013

OmniThreadLibrary Webinars

Finally I am able to announce first OmniThreadLibrary Webinars. Due to the quantity of the material we decided to split the proposed two-part High-level Multithreading with OmniThreadLibrary into three parts. They will be transmitted as follows:

  • Jun 20th: High-level multithreading, part I
    Introduction to high-level abstractions, deeper look into Async/Await, Future and Join.
  • Jun 24th: High-level multithreading, part II 
    Quick overview of high-level abstractions, deeper look into ParallelTask, BackgroundWorker and Fork/Join.
  • Jun 27th: High-level multithreading, part III
    Quick overview of high-level abstractions, deeper look into ForEach (parallel ‘for’) and Pipeline.

Each part will last about an hour and will start at 15:30 CET / 9:30 EDT / 6:30 PDT / 23:30 AEST.

Link to the registration form will appear shortly on this blog. It will also be sent to participants of the survey.

Thursday, June 06, 2013

Embarcadero Academy: DataSnap and FireDAC

Next Wednesday (12th) I’ll be talking about modern data access technologies in RAD Studio XE4.

Register here.