Q: Using the ThreadPool class

Hello everybody. I have a little trouble using the ThreadPool class.
The logic is the following.

I have a class called Render and a method in it.


public void Work()
{
Bitmap bmpFromLibrary = new Bitmap(m_path);
m_outGraph.DrawImage(bmpFromLibrary, m_xAxis, m_yAxis, m_outRegionWidth, m_outRegionHeight);
}


In another class I want to do the following thing:


Render o_Render = new Render(path, graphOutput, outputXaxis, outputYaxis, outputRegionWidth, outputRegionHeight);
ThreadPool.QueueUserWorkItem(new WaitCallback(o_Render.Work));


But it keeps giving me the following error:


Error 1 No overload for 'Work' matches delegate 'System.Threading.WaitCallback'


Any ideas how to make this work?

Thanks in advance,
kiril

[993 byte] By [kirchu] at [2007-12-28]
# 1

Change Work to:

public void Work(object state)

{

// Code here

}

SeanHederman at 2007-9-4 > top of Msdn Tech,Visual C#,Visual C# General...
# 2
Thank you very much!
kiril
kirchu at 2007-9-4 > top of Msdn Tech,Visual C#,Visual C# General...
# 3

Sean Hederman wrote:

Change Work to:

public void Work(object state)

{

// Code here

}

When I do this, I get this error in the 'Work' method.

"Parameter count mismatch."

fubak at 2007-9-4 > top of Msdn Tech,Visual C#,Visual C# General...
# 4

Double-check your code. ThreadPool.QueueUserWorkItem takes a WaitCallback which fits the signature I specified. If you still don't have any luck, post the code you're using so we can see if we can assist.

SeanHederman at 2007-9-4 > top of Msdn Tech,Visual C#,Visual C# General...
# 5
Here's my code...

private delegate void showProgressPanelDelegate();

ThreadPool.QueueUserWorkItem(new WaitCallback(showProgressPanel));


public void showProgressPanel() {

try {

if (this.InvokeRequired) {

this.BeginInvoke(new showProgressPanelDelegate(showProgressPanel));
} else { // Safe to manipulate controls directly.
progressBarPanel.Visible = true;
progressBarPanel.BringToFront();
}
} catch (Exception ex) {
string tmp = ex.Message;
}
}

fubak at 2007-9-4 > top of Msdn Tech,Visual C#,Visual C# General...
# 6

WaitCallback must have an object parameter:

private delegate void showProgressPanelDelegate(object state);

ThreadPool.QueueUserWorkItem(new WaitCallback(showProgressPanel));


public void showProgressPanel(object state) {

try {

if (this.InvokeRequired) {

this.BeginInvoke(new showProgressPanelDelegate(showProgressPanel));
} else { // Safe to manipulate controls directly.
progressBarPanel.Visible = true;
progressBarPanel.BringToFront();
}
} catch (Exception ex) {
string tmp = ex.Message;
}
}
SeanHederman at 2007-9-4 > top of Msdn Tech,Visual C#,Visual C# General...
# 7

Sean Hederman wrote:

WaitCallback must have an object parameter:

private delegate void showProgressPanelDelegate(object state);

ThreadPool.QueueUserWorkItem(new WaitCallback(showProgressPanel));


public void showProgressPanel(object state) {

try {

if (this.InvokeRequired) {

this.BeginInvoke(new showProgressPanelDelegate(showProgressPanel));
} else { // Safe to manipulate controls directly.
progressBarPanel.Visible = true;
progressBarPanel.BringToFront();
}
} catch (Exception ex) {
string tmp = ex.Message;
}
}

I tried that and it gave me a Parameter count mismatch on Application.Run

fubak at 2007-9-4 > top of Msdn Tech,Visual C#,Visual C# General...
# 8

Okay, I figured out the problem. You see WaitCallback expects an object parameter for your QueueUserWorkItem call. However, you're using BeginInvoke wrong. Rather use Invoke like I do below, and most importantly, note how I've passed in the null parameter using new object[] { null }. This is required so that the delegate dispatcher sees that there is a parameters (albeit an empty one), allowing it to marshal the call correctly.

You could use BeginInvoke, but then you must be sure to call EndInvoke on it. Also,since you're already in a worker thread, I don't see what Begin Invoke gains you.

private delegate void ShowProgressPanelDelegate(object state);

public void showProgressPanel(object state)

{

try

{

if (this.InvokeRequired)

{

this.Invoke(new ShowProgressPanelDelegate(showProgressPanel), new object[] { null });

}

else

{ // Safe to manipulate controls directly.

progressBarPanel.Visible = true;

progressBarPanel.BringToFront();

}

}

catch (Exception ex)

{

string tmp = ex.Message;

}

}

private void button1_Click(object sender, EventArgs e)

{

ThreadPool.QueueUserWorkItem(new WaitCallback(showProgressPanel));

}

SeanHederman at 2007-9-4 > top of Msdn Tech,Visual C#,Visual C# General...
# 9
Awesome, that worked...now, how do I make that thread complete before moving on?

This 'ProgressPanel' has a button on it that has an animated image on it. Right now, when the panel displays it shows a transparent box in the panel where the button should be. I'm assuming that I need to make the thread complete before moving on?

fubak at 2007-9-4 > top of Msdn Tech,Visual C#,Visual C# General...
# 10

No, when the thread exits the showProgressPanel method it will have completed successfully, so there's nothing you need to do there. There must be some other reason why the panel is showing transparent.

SeanHederman at 2007-9-4 > top of Msdn Tech,Visual C#,Visual C# General...
# 11
Nevermind, I called this.Update() on my thread to update the control. However, the image on the button is still not animated. Any ideas?
fubak at 2007-9-4 > top of Msdn Tech,Visual C#,Visual C# General...
# 12
Not really, what kind of animated image is it?

SeanHederman at 2007-9-4 > top of Msdn Tech,Visual C#,Visual C# General...
# 13
it's the Mac 'Please Wait' icon. It's a bunch of lines in a circle and they change color one at a time and go in a circle. It's basically just a 'Thinking' icon.
fubak at 2007-9-4 > top of Msdn Tech,Visual C#,Visual C# General...
# 14

Sorry, I meant what image format is it? GIF?

SeanHederman at 2007-9-4 > top of Msdn Tech,Visual C#,Visual C# General...