Tutorial :Passing data back from external dll with threads



Question:

I have a common comms library that i have written to communicate with our hardware over TCP/IP

The common library allows both the clients application and our engineer tool to share common code. The common library runs threads that need to return data back to forms.

I have some working code but I feel that there must be an easier way to do it.

This is a simplified version of what i have...

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();          }        }  }  


Solution:1

What about creating an event on the Discover class and the Form subscribes to the event, instead of passing delegates around.


Solution:2

Take a look at the BackgroundWorker class:

BackgroundWorker Component Overview


Solution:3

Let's say that you are performing a search that will result in a List<Customer> object. One rather straight-forward and simple approach is then to raise an event when the search is done, using a special EventArgs class carrying the result:

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

...in the search class:

// 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);      }  }  

...and in the 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());      }  }  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »