更新跨线呼叫错误的通用方法

时间:2019-05-01 20:37:59

标签: c# winforms

我有一个表格,您需要使用thread-safe calls to Windows Forms controls

进行多次更新

执行此操作的代码节段重复多次。为了重构,我创建了一种通用的更新方法。

我有一个类来注册将在常规metdo中使用的方法:

public class ListOfUpdateMethods
{
    public delegate void Metodo();
    private List<Metodo> MetodosPreAtualizacao;
    private List<Metodo> MetodosAtualizacao;

    public ListOfUpdateMethods()
    {
        this.MetodosPreAtualizacao = new List<Metodo>();
        this.MetodosAtualizacao = new List<Metodo>();
    }

    public void AddMetodosPreAtualizacao(Metodo m)
    {
        this.MetodosPreAtualizacao.Add(m);
    }

    public void AddMetodosAtualizacao(Metodo m)
    {
        this.MetodosPreAtualizacao.Add(m);
    }

    public void ExecutaMetodosPreAtualizacao()
    {
        foreach (var m in this.MetodosPreAtualizacao)
            m();
    }

    public void ExecutaMetodosAtualizacao()
    {
        foreach (var m in this.MetodosAtualizacao)
            m();
    }
}

方法:

//General method for updating all Controls as needed 

    private void UpdadeControl(ListOfUpdateMethods list, Control control)
    {
        //Execute required methods before updating the control
        list.ExecutaMetodosPreAtualizacao();

        if (control.InvokeRequired)
        {
            var up = new Updates(UpdadeControl);
            Invoke(up, new object[] { list, control });
        }
        else
        {
            //Execute methods needed to update control
            list.ExecutaMetodosAtualizacao();

        }
    }

当我想更新某些控件时,我要做的是:

ListOfUpdateMethods VariavelDeInstancia = new ListOfUpdateMethods();
UpdateStopXRayTimer.AddMetodosAtualizacao(MetodoComInstrucoesQUeAtualizaOControle);
UpdadeControl(VariavelDeInstancia, ControleASerAtualizado);

但是,当调用MetodoComInstrucoesQUeAtualizaOControle时,交叉的theadins会发生访问异常。也就是说,该方法不能在主踏步上运行。

使用此方法的示例如下:

void MetodoComInstrucoesQUeAtualizaOControle()
{
   ControleASerAtualizado = "Text";
}

有人对如何解决上述问题有任何提示吗?

1 个答案:

答案 0 :(得分:0)

因为您的代码有错误。在下面提示。

public class ListOfUpdateMethods
{
    public delegate void Metodo();
    private List<Metodo> MetodosPreAtualizacao;
    private List<Metodo> MetodosAtualizacao;

    public ListOfUpdateMethods()
    {
        this.MetodosPreAtualizacao = new List<Metodo>();
        this.MetodosAtualizacao = new List<Metodo>();
    }

    public void AddMetodosPreAtualizacao(Metodo m)
    {
        this.MetodosPreAtualizacao.Add(m);
    }

    public void AddMetodosAtualizacao(Metodo m)
    {
       // change this code.
       // this.MetodosPreAtualizacao.Add(m);
       this.MetodosAtualizacao.Add(m);
    }

    public void ExecutaMetodosPreAtualizacao()
    {
        foreach (var m in this.MetodosPreAtualizacao)
            m();
    }

    public void ExecutaMetodosAtualizacao()
    {
        foreach (var m in this.MetodosAtualizacao)
            m();
    }
}

我建议您将UpdadeControl方法更改为以下方法。

private void UpdadeControl(ListOfUpdateMethods list, Control control)
{
    // this method can't added the UI operate. 
    // If you added the UI operate delegate. It will throw the exception.
    list.ExecutaMetodosPreAtualizacao();

    if (control.InvokeRequired)
    {
        // you can use Action delegate. Action delegate is so good.
        var action = new Action<ListOfUpdateMethods, Control>(UpdadeControl);
        control.Invoke(action, new object[] { list, control });
    }
    else
    {
        //Execute methods needed to update control
        list.ExecutaMetodosAtualizacao();

    }
}