我有一个棘手的情况,想知道是否有人可以对此事有所了解:
我有一个像这样调用的阻塞收集操作工作者
ultraHash hash = new ultraHash(lblFolder.Text, (Action) (() => {
textBox1.Text = self.getMD5();
});
runQueue.addAction(hash);
现在“自我”的东西是伪代码,这就是为什么,这就是(worker
容器类在哪里)runQueue
BlockingCollection
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();
}
}
现在我想要发生的是 Action (() => {}
第一个片段中的匿名方法在队列完成后执行并且能够包含 MD5 总和。我知道这里存在线程安全问题,所以我知道我必须invoke
回到textBox1
所在的父线程,但目前我只是迷失了如何做到这一点(甚至可能吗?)
编辑
我通常不会“编辑”答案,但如果其他人遇到这个问题,这是我最终使用的代码,这要归功于usr
. 注意BeginInvoke
ultraHash hash = null;
hash = new ultraHash(lblFolder.Text, (Action) (() => {
this.BeginInvoke((Action) (() => {
txtMain.Text = hash.getMD5();
}));
}));
runQueue.addAction(hash);
另外,如果您想知道我为什么这样做,那只是为了让我可以“监视”文件夹中的任何文件更改,然后存储元数据更改,因为可以将整个文件夹拖入/拖出,因此需要排队机制在 FIFO 队列中,父文件夹也被散列,因此任何文件更改都需要冒泡,最后可能是文件在尝试散列时被锁定,在这种情况下,FIFO 队列可以等待