VB.Net Using Delegates for Form Updates from Worker Threads
by Tim on September 21, 2011
At Geekup Preston this week a conversation with @surlydev led to an explanation of how to use delegates to update a UI from a worker thread. Talk is cheap, and a code sample goes along way to help explain.
Imports System.Threading
Public Class DelegateDemo
' imagine a form with Button1 + Label1
' the thread
Private _worker As Thread
' declare a kind of delegate with the signature you want
Private Delegate Sub UpdateDelegate(ByVal s As String)
' declare an implmentation with matching signature
Private Sub UpdateStatus(ByVal s As String)
Me.Label1.Text = s
End Sub
' kick-off the worker thread
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' start a worker
If _worker Is Nothing Then
_worker = New Thread(AddressOf WorkerMain)
_worker.Start()
End If
End Sub
' Worker thread
Private Sub WorkerMain()
Dim x As Integer = 0
Do
' increment
x += 1
' update UI + sleep
' this executes delegate + params on thread that owns the form
Dim msg As String = String.Format("Hello {0}", x)
Dim del As UpdateDelegate = AddressOf UpdateStatus
Me.Invoke(del, msg)
' half a second snooze
Thread.Sleep(500)
Loop While x < 30
' thread's dead baby (will terminate when it exits this sub)
_worker = Nothing
End Sub
End Class
Social Media Fragmentation
by Tim on July 19, 2011
The arrival of Google+ has prompted me to rethink my use of social networks like Facebook and Twitter for publishing information and status updates. Already, some friends have moved away from Twitter and it has made me realise that the networks are gatekeepers to my friendships.
Something I read about social networks a while ago stuck in my mind… that ourselves and our relationships are being commoditised – we are the product.
Without question, social networks make it easier than ever for us to stay connected and make new connections – but I fear our voices are getting diluted across the ever growing social media landscape.
It occurs to me that as the number of social networks I participate on increases that my presence on each diminishes and my friends become more distributed. Furthermore, the energy required to maintain a cohesive mental model of who belongs where is becoming too great.
For many years I maintained a blog, but moved into Twitter and Facebook as the barrier to sharing tidbits of news and occasional photos was substantially lower than publishing a new post on my blog. As my friends were all users in the same spaces it made little difference – but now my friends are fragmented all over the place.
This post symbolises a change of strategy. I don’t think the solution is some kind of aggregator, but is to relocate.
I think I’m going to hangout here for a while.
And to see how easy it is to publish with modern tools, here’s a photo of my dog Millie.
Namaste.
Consuming DataSift Streams with Node.js
by Tim on February 17, 2011
This Node.js code sample consumes a DataSift stream and invokes a callback with each message object as it arrives.
The DataSift streams contain one JSON object per line, and may receive occasional empty lines to act as a “you are still connected” signal. The sample callback echoes each message out to the console.
/*
* Consuming a DataSift stream using node.js
* To use this sample, you will need your DataSift username, API key and a stream identifier.
* Copyright 2011 Tim Hastings.
* Released under the MIT License with no warranties given.
* Have fun!
*
**/
var http = require('http');
function consumeDataSiftStream(username, apikey, stream_id, callback) {
var buffer = '';
// parse the JSON of a single line and invoke the callback
function processLine(line) {
try {
var obj = JSON.parse(line);
callback(obj);
} catch (err) {
// parse failure or error from callback
console.log(JSON.stringify(err, null, '\t'));
}
}
// handle the HTTP response and attach handlers
var response_handler = function(resp) {
// data handler
resp.addListener('data', function(chunk) {
// append to buffer
buffer = buffer + chunk;
// consume any newlines
var pos = buffer.indexOf("\n");
while (pos >= 0) {
// take the line from the buffer
var line = buffer.substring(0, pos);
// remove from buffer
buffer = buffer.substring(pos + 1);
// pass to line handler if not empty
if (!line.match(/^\s*$/)) {
processLine(line);
}
// any more lines in the buffer?
pos = buffer.indexOf("\n");
}
});
// close handler
resp.addListener('end', function() {
// any remaining buffer will not have a newline in, so invoke
if (buffer.length > 0) {
processLine(buffer);
}
});
};
// create the connection and attach response handler
var path = "/"+stream_id+"?api_key="+escape(apikey)+"&username="+escape(username);
var client = http.createClient(80, "stream.datasift.net");
var headers = {host: "stream.datasift.net"};
var req = client.request('GET', path, headers);
req.addListener('response', response_handler);
req.write('');
req.end();
}
// test it
var username = 'USERNAME';
var apikey = 'APIKEY';
var stream_id = 'STREAM_ID';
consumeDataSiftStream(username, apikey, stream_id, function(obj) {
// is this an error or idle msg?
if (obj.status) {
console.log(JSON.stringify(obj, null, '\t'));
} else if (obj.tick) {
console.log();
} else if (obj.interaction && obj.interaction.author) {
console.log(obj.interaction.author.username+"\n "+obj.interaction.content);
} else {
console.log(JSON.stringify(obj));
}
});
Welcome 2011
by Tim on January 21, 2011
A new year and a new start, so here is the obligatory new blog. This year sees the final and necessary step in my long, drawn out plan to step into the world of freelancing and start-ups. Actually doing it.
In the year ahead I am looking forward to working with many of the friends I have met online and in person at Geekup, many BarCamps, PodCamps, hackathons and conferences. From a technology perspective, I would like to make full use of the tools and APIs I have been using in my projects rather than the more conventional enterprise technology stacks.
As well as different people and tools I am also looking forward to a change in lifestyle with a reduced commute to the office and a better work/life/wife balance. As I type, Ryan is sat next to me doing some virtual painting :-)
This blog will, from time to time, be an outlet for unashamedly geeky content, but for today, it looks like I have successfully managed to avoid a long list of geeky tech-speak.
Anyhoo, I must dash and crack on.
You can follow me on Twitter: @timhastings





