Reputation: 2546
I have a tricky situation and was wondering if anyone could shed any light on the matter:
I have a blocking collection action worker that is called like this
ultraHash hash = new ultraHash(lblFolder.Text, (Action) (() => {
textBox1.Text = self.getMD5();
});
runQueue.addAction(hash);
now the "self" thing is there is pseudo code, and this is why, this is the worker
(where runQueue
is the BlockingCollection
container class)
class ultraHash
{
string _filePath;
Action _onComplete;
string _md5;
public ultraHash(string filePath)
{
_filePath = filePath;
}
public ultraHash(string filePath, Action onComplete) : this(filePath) //constructor chaining
{
_onComplete = onComplete;
}
public override void action()
{
using (var md5 = MD5.Create())
{
try
{
using (var stream = File.OpenRead(_filePath))
{
_md5 = MakeHashString(md5.ComputeHash(stream));
if (_onComplete != null) _onComplete();
}
}
catch (IOException)
{
/***
* file is Busy
*/
}
}
}
public string getMD5()
{
return _md5;
}
private string MakeHashString(byte[] hashBytes)
{
StringBuilder hash = new StringBuilder(32);
foreach (byte b in hashBytes)
{
hash.Append(b.ToString("X2").ToLower());
}
return hashBytes.ToString();
}
}
now what I want to happen is for the anonymous method Action (() => {}
in the first snippet to execute after the queue has completed and be able to contain the MD5 sum. I know there is thread safety issues here, so I understand I have to invoke
this back to the parent thread where textBox1
resides, but at the moment I am just lost as to how to do this (is it even possible?)
EDIT
I don't normally "edit" answers but in case anyone else hits this issue this is the code I eventually used, thanks to the answer from usr
. Notice the BeginInvoke
ultraHash hash = null;
hash = new ultraHash(lblFolder.Text, (Action) (() => {
this.BeginInvoke((Action) (() => {
txtMain.Text = hash.getMD5();
}));
}));
runQueue.addAction(hash);
also, if you are wondering why I did this, it is merely so that I can "watch" a folder for any file changes and then store meta data changes, since entire folders can be dragged in/out there needs to be a queueing mechanism in a FIFO queue, also the parent folders are hashed too, so any file alterations need to bubble up, lastly it may be that a file is locked when it is trying to be hashed in which case a FIFO queue can wait
Upvotes: 3
Views: 305
Reputation: 171178
Probably, you should pass the hash as an argument to your onComplete
function. getMD5
does not need to exist.
If you insists on doing it just this way you need a little initialization dance:
ultraHash hash = null;
hash = new ultraHash(lblFolder.Text, (Action) (() => {
textBox1.Text = hash.getMD5();
});
The whole design of the ultraHash
seems strange. Is it really necessary for that class to exist? A single static method that computes the hash should be enough.
Upvotes: 1