2

我有一个棘手的情况,想知道是否有人可以对此事有所了解:

我有一个像这样调用的阻塞收集操作工作者

 ultraHash hash = new ultraHash(lblFolder.Text, (Action) (() => {
       textBox1.Text = self.getMD5();
 });
 runQueue.addAction(hash);

现在“自我”的东西是伪代码,这就是为什么,这就是(worker容器类在哪里)runQueueBlockingCollection

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 队列可以等待

4

1 回答 1

1

可能,您应该将散列作为参数传递给您的onComplete函数。getMD5不需要存在。

如果你坚持这样做,你需要一点初始化舞蹈:

ultraHash hash = null;
hash = new ultraHash(lblFolder.Text, (Action) (() => {
           textBox1.Text = hash.getMD5();
     });

整个设计ultraHash看起来很奇怪。那个类真的有必要存在吗?计算哈希的单个静态方法就足够了。

于 2015-05-18T18:31:33.250 回答