使用c#中的invoke在线程之间发送多个对象

时间:2012-04-28 08:07:24

标签: c# invoke

我遇到了将加载的数据从一个线程传递到另一个线程以将数据添加到表单的问题。我在“var obj = new object [] {names}”中添加了另一个对象,并得到了“参数计数不匹配”。我仍然希望将第二个线程中的“LoadData()”中的“Clients”和“Messages”传递给第一个中的“UpdateFormMethod()”,但我不知道该怎么做。如果有人能帮我解决这个问题,我将不胜感激。

以下是一个类中代码的重要部分:

private readonly Thread _thread;
    public readonly Loader Loader = new Loader();
    public Dictionary<string, Client> Clients;
    public Dictionary<string, Message> Messages;
    private bool _stopData = false;
    public delegate void UpdateForm(object data);
    public UpdateForm MyDelegate;

    public Fcon() {
        InitializeComponent();
        MyDelegate = new UpdateForm(UpdateFormMethod);
        _thread = new Thread(LoadData);
        _thread.Start();
    }

    public void UpdateFormMethod(object data) {
        foreach (var str in ((IEnumerable<string>)data).Where(str => !fcon_container_users_list.Items.Contains(str))) {
            fcon_container_users_list.Items.Insert(0, str);
        }
    }

    public void LoadData() {
        while (!_stopData) {
            Clients = Loader.GetClients(Operator);
            Messages = Loader.GetMessages(Operator);
            var status = Loader.SetStatus(Operator);
            var names = new string[Clients.Count];
            var x = 0;
            foreach (var kvp in Clients) {
                names[x] = "user_" + kvp.Value.id_fcon_client;
                x++;
            }
            var obj = new object[] { names };
            this.Invoke(this.MyDelegate, obj);    
            Thread.Sleep(1000);
        }
    }

    public void StopData() {
        _stopData = true;
    }

2 个答案:

答案 0 :(得分:1)

听起来你并不完全清楚签名的来源。它是您自己的委托 - 如果您想更改签名,只需更改委托的签名和实现它的方法:

public delegate void UpdateForm(IEnumerable<string> data, int foo);

...

public void UpdateFormMethod(IEnumerable<string> data, int foo) {
    foreach (var str in data.Where(str => 
               !fcon_container_users_list.Items.Contains(str))) {
        fcon_container_users_list.Items.Insert(0, str);
    }
}

然后:

var obj = new object[] { names, someIntVariable };
this.Invoke(this.MyDelegate, obj);

或更简单:

this.Invoke(this.MyDelegate, names, someIntVariable);

我可能会使用现有的Action<T>Action<T1, T2>代理,而不是创建新的代理,但OR T Func&lt; T1 [,T2]&gt;如果您需要返回类型。

答案 1 :(得分:-1)

您正在传递一个对象[],但您应该只传入对象。

发送它只是把它作为对象,即

this.Invoke(this.MyDelegate, (object)obj);

并将其转换回方法内部。他们将对象指定为参数类型的原因是它允许他们不必指定许多我认​​为的签名