2009-05-13 5 views
0

ich eine gemeinsame Comms Bibliothek habe, die ich geschrieben habe, zusammen mit unserer Hardware über TCP/IPPassing Daten zurück von einem externen dll mit Gewinden

Die gemeinsame Bibliothek erlaubt es sowohl die Kunden-Anwendung und unser Ingenieur-Tool zu teilen gemeinsamen Code zu kommunizieren . Die allgemeine Bibliothek führt Threads aus, die Daten an Formulare zurückgeben müssen.

Ich habe einige Arbeitscode, aber ich denke, dass es einen einfacheren Weg geben muss, es zu tun.

Dies ist eine vereinfachte Version von dem, was ich habe ...

namespace EngineerTool 
{ 

    public delegate void DelegateSearchFinished(); 

    public partial class MainForm : Form 
    { 
     public DelegateSearchFinished d_SearchFinished; 
     Discover discovery; 

     public MainForm() 
     { 
      InitializeComponent(); 
      discovery = new Discover(this.FinishedSearchInvoke); 
      d_SearchFinished = new DelegateSearchFinished(this.FinishedSearch); 
      discovery.Start(); 
     } 

     public void FinishedSearchInvoke() 
     { 
      this.Invoke(this.d_SearchFinished, new Object[] {}); 
     } 

     public void FinishedSearch() 
     { 
      // Search has finished here! 
     } 
    } 
} 

namespace DiscoveryTool 
{ 
    public delegate void DelegateSearchFinished(); 

    public class Discover 
    { 
     DelegateSearchFinished _callFinished; 

     public Discover(DelegateSearchFinished callFinished) 
     { 
      _callFinished = callFinished; 
     } 

     public void Start() 
     { 
      // starts thread and stuff 
     } 

     public void ThreadWorker() 
     { 



      _callFinished(); 
     } 

    } 
} 

Antwort

0

Was ist ein Event auf der Discover-Klasse erstellen und Das Formular abonniert die Veranstaltung, anstatt die Teilnehmer herumzuleiten.

+0

klingt wie eine gute Idee, wird diese alle Thread-sicher sein? –

+0

Ja ... Sie abonnieren basierend auf dem instanziierten Objekt. Sie können eine Thread-ID in den Ereignisargumenten zurücksenden, wenn Sie wissen müssen, wer die Arbeit verarbeitet hat. – CSharpAtl

+0

hat funktioniert perfekt –

0

Angenommen, Sie führen eine Suche durch, die zu einem List<Customer> Objekt führt. Ein eher geradlinig und einfacher Ansatz ist dann ein Ereignis zu erhöhen, wenn die Suche abgeschlossen ist, mit einer speziellen EventArgs Klasse trägt das Ergebnis:

public class CustomerSearchEventArgs : EventArgs 
{ 
    public List<Customer> Customers { get; private set; } 
    public CustomerSearchEventArgs(List<Customer> customers) 
    { 
     Customers = customers; 
    } 
} 

... in der Suchklasse:

// the parameter is there to conform to the signature of the WaitDelegate 
// used when invoking the method using the ThreadPool 
public void Search(object state) 
{  
    List<Customer> result = new List<Customer>(); 
    // perform the search, populate the result list 
    // call a method to raise the event 
    OnSearchFinished(new CustomerSearchEventArgs(result)); 
} 

protected void OnSearchFinished(CustomerSearchEventArgs e) 
{ 
    EventHandler<CustomerSearchEventArgs> searchFinished = this.SearchFinished; 
    if (searchFinished != null) 
    { 
     searchFinished(this, e); 
    } 
} 

... und in der Form:

private delegate void CustomerListHandler(List<Customer> customers); 

private void StartSearch() 
{ 
    CustomerSearch search = new CustomerSearch(); 
    search.SearchFinished += new EventHandler<CustomerSearchEventArgs>(Search_SearchFinished); 
    ThreadPool.QueueUserWorkItem(search.Search); 
} 
private void Search_SearchFinished(object sender, CustomerSearchEventArgs e) 
{ 
    SearchFinished(e.Customers); 
} 

private void SearchFinished(List<Customer> list) 
{ 
    if (this.InvokeRequired) 
    { 
     // the method is NOT executing on the UI thread; we 
     // need to invoke it on the right thread 
     this.Invoke(new CustomerListHandler(SearchFinished), list); 
    } 
    else 
    { 
     lstCustomers.Items.Clear(); 
     lstCustomers.DisplayMember = "Name"; 
     lstCustomers.Items.AddRange(list.ToArray()); 
    } 
} 
+0

ich schaffte es, ohne eine EventArgs-Klasse zu haben. Ich habe: öffentlichen Delegaten void NegotiateStatus (String-Status); öffentliche Veranstaltung NegotiateStatus OnNegotiateStatus; dann kann ich einfach anrufen OnNegotiateStatus ("string") dann in meiner Form, ich habe nur conNeg.OnNegotiateStatus + = new NegotiateConnection.NegotiateStatus (this.NegotiateStatus); –

Verwandte Themen