473,320 Members | 1,831 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Threading fun! User controls with multithreading.

I'm having some difficulty getting controls to work with multithreading.
Basically, I want to begin a long running operation on another thread when a
button is clicked, and then disable that button until the operation
completes. When the operation finishes, I want the button to re-enable. To
make things more interesting, this button is located on a TabPage in a
TabControl on the main Form, so it's three containers deep. I'm using C# 2.0
Beta 2. Here's basically what my code looks like:

// Button clicked event handler
public void btnRun_click(/*params*/)
{
btnRun.enabled = false;
Thread query = new Thread(new ThreadStart(operation));
query.start();
}

private void operation()
{
/* Do a long running SQL query */
this.Parent.Parent.Parent.BeginInvoke(done());
}

private Delegate done()
{
btnRun.enabled = true;
}

When I run this code, btnRun.enabled = true throws an exception saying that
I can't access the Button from a different thread than it was created on.
However, I was under the impression that that whole point of
Control.BeginInvoke was to run a method on the same thread that the control
was created on. I've tried this using the BeginInvoke method of the Form,
the TabControl, and the TabPage, and get the same result on all three.
Anyone know how to resolve this? Thanks!
Nov 22 '05 #1
3 2257
Warren <Wa****@discussions.microsoft.com> wrote:
I'm having some difficulty getting controls to work with multithreading.
Basically, I want to begin a long running operation on another thread when a
button is clicked, and then disable that button until the operation
completes. When the operation finishes, I want the button to re-enable. To
make things more interesting, this button is located on a TabPage in a
TabControl on the main Form, so it's three containers deep. I'm using C# 2.0
Beta 2. Here's basically what my code looks like:

// Button clicked event handler
public void btnRun_click(/*params*/)
{
btnRun.enabled = false;
Thread query = new Thread(new ThreadStart(operation));
query.start();
}

private void operation()
{
/* Do a long running SQL query */
this.Parent.Parent.Parent.BeginInvoke(done());
}

private Delegate done()
{
btnRun.enabled = true;
}

When I run this code, btnRun.enabled = true throws an exception saying that
I can't access the Button from a different thread than it was created on.
However, I was under the impression that that whole point of
Control.BeginInvoke was to run a method on the same thread that the control
was created on. I've tried this using the BeginInvoke method of the Form,
the TabControl, and the TabPage, and get the same result on all three.
Anyone know how to resolve this? Thanks!


That certainly looks fairly odd. Could you post a short but complete
program which demonstrates the problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 22 '05 #2
Ok, here goes. I understand controls can only be accessed by the thread that
created them. I thought that a container's BeginInvoke method would force
the delegate passed to it to execute asynchronously on said thread.

Below, I create a Label and add it to my Form. I then create a new thread
running the method RunThread. RunThread sleeps for 1 second (simulating work
being done), and then uses the Form’s BeginInvoke method to call the
ThreadFinished method. ThreadFinished updates the Label to reflect the
program’s status. I believe the ThreadFinished method should be running on
the same thread that created the Form because I used the Form’s BeginInvoke
method. However, I instead get an AccessViolationException at the line that
updates the Label’s text telling me that I can only access controls on the
thread that created them. Can anyone tell me why this is happening? I’m
using C# 2.0 Beta 2.

I just created a blank project and added refrences to System.Windows.Forms
and System.Drawing. This is the only code file in the project.

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Threading;

namespace Project1
{
class Class1 : Form
{
private Label lblStatus;

public static void Main()
{
Application.Run(new Class1());
}

public Class1()
{
lblStatus = new Label();
lblStatus.Text = "Before thread";
lblStatus.Location = new Point(50, 50);
this.Controls.Add(lblStatus);

this.Size = new Size(200, 200);
this.Visible = true;
this.Show();

Thread t = new Thread(new ThreadStart(RunThread));
t.Start();
}

private void RunThread()
{
Thread.Sleep(1000);
this.BeginInvoke(ThreadFinished());
}

private Delegate ThreadFinished()
{
lblStatus.Text = "After thread";
return null;
}
}
}
Nov 22 '05 #3
Warren <Wa****@discussions.microsoft.com> wrote:
Ok, here goes. I understand controls can only be accessed by the thread that
created them. I thought that a container's BeginInvoke method would force
the delegate passed to it to execute asynchronously on said thread.

Below, I create a Label and add it to my Form. I then create a new thread
running the method RunThread. RunThread sleeps for 1 second (simulating work
being done), and then uses the Form?s BeginInvoke method to call the
ThreadFinished method. ThreadFinished updates the Label to reflect the
program?s status. I believe the ThreadFinished method should be running on
the same thread that created the Form because I used the Form?s BeginInvoke
method. However, I instead get an AccessViolationException at the line that
updates the Label?s text telling me that I can only access controls on the
thread that created them. Can anyone tell me why this is happening? I?m
using C# 2.0 Beta 2.


Right - the problem is that you're *calling* ThreadFinished rather than
providing a *delegate* to ThreadFinished. In other words, you should be
doing:

this.BeginInvoke (ThreadFinished);

rather than

this.BeginInvoke (ThreadFinished());

Currently you're effectively doing:

Delegate x = ThreadFinish(); // Eek! This is changing the text in the
// worker thread!
this.BeginInvoke (x); // This does nothing as x is actually null.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 22 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Aahz | last post by:
There were some posts recently discussing whether it's poor style to put import statements inside functions. I recently got reminded that there's one very good reason to avoid it: Python has an...
2
by: Egor Bolonev | last post by:
hi all my program terminates with error i dont know why it tells 'TypeError: run() takes exactly 1 argument (10 given)' =program==================== import os, os.path, threading, sys def...
2
by: Rafal 'Raf256' Maj | last post by:
Hi, I have base class that defines function 'fun'. This function is overloaded - it can be used fr argument int or for const char* Function is virtual. Now I create a dervied class cB, and I...
77
by: Jon Skeet [C# MVP] | last post by:
Please excuse the cross-post - I'm pretty sure I've had interest in the article on all the groups this is posted to. I've finally managed to finish my article on multi-threading - at least for...
2
by: W.G. Rowland | last post by:
In some ways I'm starting to miss the simpler days of VB5.. Anyway, here's my problem. I'm trying to build a MSDE client using an MDI Parent/Child interface. Enough of the tasks the program...
16
by: One Handed Man \( OHM - Terry Burns \) | last post by:
Sorry if this gets duplicated, but I posted it and cant see it for a long time so repost. . . I have an application which is writing to a graphics object, the main UI thread and a worker thread...
41
by: km | last post by:
Hi all, Is there any PEP to introduce true threading features into python's next version as in java? i mean without having GIL. when compared to other languages, python is fun to code but i feel...
2
by: VMI | last post by:
I'm filling up a gridview and the underlying datatable has about 30,000 records, so it takes some time before I can see the page again with the records on the gridview. Is there any type of...
9
by: cgwalters | last post by:
Hi, I've recently been working on an application which does quite a bit of searching through large data structures and string matching, and I was thinking that it would help to put some of this...
14
by: Akihiro KAYAMA | last post by:
Hi all. I found cooperative multi-threading(only one thread runs at once, explicit thread switching) is useful for writing some simulators. With it, I'm able to be free from annoying mutual...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.