CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 2 of 2
  1. #1
    Join Date
    Nov 2011
    Posts
    63

    manipulating control across threads

    Hello,

    I'm trying to do some multithread using Invoke() in order to set the values of Window Form controls, and I need some help.

    The situation is this. I have a form on which there are many controls. There is a "connect" button on this form. When this button is clicked, it attempts to connect to a database which can take a while. Therefore, we want to bring up a new form with a progress bar while it is connecting.

    I have learned, however, that in order for this form/progress bar to work properly (specifically, to prevent it from hiding behind the main application form and to start animating the progress bar immediately), it needs to run in a separate thread from that which does the database connecting, and specifically it has to run in the main thread while the database connecting work in done in a new thread.

    So far, this has not been too difficult. The difficulty comes in when the new thread which does the database connecting has to manipulate the controls on the form (the one with the "connect" button) and I get a cross-thread operation error. This is the part I need some guidance on.

    Most examples start with a check on InvokeRequired (like this: if (control.InvokeRequired) { // invoke here }). One of the problems I'm having, however, is that the controls I'm using don't have the InvokeRequired flag (I'm using Telerik controls). So instead I'm trying to detect if I'm on the main thread or not. This may not be the best method, but it's kind of where I'm at right now. It's at this point that I need some guidance on how to manipulate controls from across threads, especially when InvokeRequired is not available.

    Here's some of the code I have in place:

    Code:
    // Function that does the work:
            private void PopulateConnectionNameListView(String currentdatabase, bool mayInvoke = true)
            {
    
                if (mayInvoke && System.Threading.Thread.CurrentThread.ManagedThreadId != 1) // is this the main thread?
                {
    		// Then better invoke:
                    this.Invoke(new MethodInvoker(delegate { PopulateConnectionNameListView(currentdatabase, false); }));
                    return;
                }
    
    	    // This is the line that requires invoking
                radListViewConnectionName.Items.Clear();
    ...
    }
    Code:
    	// Here are the worker functions that do the database connecting in the background:
            private void BackgroundWorker_DoWork(object sender, EventArgs e)
            {
                ConnectToSelectedDB(); // This is the main entry point for the work. It will eventually call PopulateConnectionNameListView()
            }
    
            private void BackgroundWorker_WorkCompleted(object sender, EventArgs e)
            {
            }
    Code:
    // Here's the button click handler for the connect button:
            private void radButtonConnection_Click(object sender, System.EventArgs e)
            {
                System.ComponentModel.BackgroundWorker bw = new System.ComponentModel.BackgroundWorker();
                bw.DoWork += new System.ComponentModel.DoWorkEventHandler(BackgroundWorker_DoWork);
                bw.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(BackgroundWorker_WorkCompleted);
                bw.RunWorkerAsync();
    
    	    // Here's where I bring up my dialog with the progress bar:
                frmRadWaitDialog waitDialog = new frmRadWaitDialog();
                waitDialog.Show();
            }

  2. #2
    Join Date
    Sep 2015
    Posts
    10

    Re: manipulating control across threads

    Cross Thread Exception Raising


    Code:
    <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="WpfApplication1.SecondaryUiThreadWindow"
      Height="240" Width="500" Closed="SecondaryUiThreadWindow_Closed">
      <Button Click="r">Raise an Exception on the Secondary UI Thread</Button>
    
    </Window>
    //File:Window.xaml.cs
    using System; 
    using System.Threading;
    using System.Windows; 
    using System.Windows.Threading;
    
    namespace WpfApplication1
    {
        public partial class SecondaryUiThreadWindow : Window
        {
            public SecondaryUiThreadWindow()
            {
                InitializeComponent();
    
                this.Title = Thread.CurrentThread.ManagedThreadId+"";
            }
            void r(object sender, RoutedEventArgs e)
            {
                throw new Exception(Dispatcher.CurrentDispatcher.Thread.ManagedThreadId+"");
            }
            void SecondaryUiThreadWindow_Closed(object sender, EventArgs e)
            {
                Dispatcher.CurrentDispatcher.InvokeShutdown();
            }
        }
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured