2012-04-28 45 views
1

我在将加载的数据从一个线程传递到另一个线程以将数据添加到表单中时出现问题。我将另一个对象添加到“var obj = new object [] {names}”中,并得到“参数计数不匹配”。我仍然希望将第二个线程中的“LoadData()”中的“客户端”和“消息”传递给第一个中的“UpdateFormMethod()”,但我不知道如何去做。如果有人能够帮助我解决这个问题,我将不胜感激。使用c中的调用在线程之间发送多个对象#

下面的代码的一个类中的重要组成部分:

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; 
    } 
+0

请更明确地说明你的问题是什么。 (1)你究竟做了什么“添加其他对象”? (2)通过“我还是更愿意......”,你的意思是“我的问题是我怎么能...”,或者是真正的问题吗? – 2012-04-28 08:14:58

回答

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>代表而不是创建新的代表,虽然或T功能< T1 [,T2] >如果您需要返回类型。

+0

非常感谢!这种方式完美地工作。并感谢关于行动的建议,我会读到它。这是我第一周的C#,我需要快速学习。 – Phillyfisher 2012-04-28 08:39:59

-1

要传递一个Object []中,但你应该只在对象传递。

要只投它作为对象即

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

和将它转换回所述方法内发送。他们将对象指定为参数类型的原因是,它允许他们不必指定很多很多的签名我认为

+0

为什么要为此创建一个数组,然后将所有位重新放回方法中,只要更改委托类型就简单多了? – 2012-04-28 08:17:19

+0

@JonSkeet - 我认为这是一个系统定义的代表。虽然给予代表的签名,我的答案仍然是:)顺便说一句好评:)我不能与'Skeet'争论! – 2012-04-28 08:21:39