
Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
> At a complete guess, you're calling Invoke on the delegate rather than
> on the control. However, a complete example would be better. Could you
> post one?
>
> See http://www.pobox.com/~skeet/csharp/complete.html for details of
> what I mean by that.
Hi again,
I'm unable to create such short example, but I've tried to copy/paste the
parts of where the threading problem occurs. There are only three classes
involved, I've added comments to describe what I've tried to do.
////////////////////////////////////////////////////////////////////////
// Code in the main thread
// This code start the entire processing of the reports. This is a Form
class instance.
// The exception message should end up here, so it can be shown.
////////////////////////////////////////////////////////////////////////
private void btnPrint_Click(object sender, EventArgs e)
{
ReportsGateway.CreateReport(userLaen, arnIDs, ardIDs, true, true, this);
}
// I've tried having this callback method in the child thread, but did not
work.
// I would actually rather have it in the child thread, because others might
start
// the report processing in the future.
public void ShowThreadError(string text)
{
throw new BofException("Error generating reports." + Environment.NewLine
+ Environment.NewLine + text);
}
////////////////////////////////////////////////////////////////////////
// Code in the report helper (gateway), an in-between layer.
// This is where the child thread is created. This is a static class,
// inheriting from Object
////////////////////////////////////////////////////////////////////////
public static void CreateReport(int userLaen, int[] arnIDs, int[] ardIDs,
bool onlyPreview, bool printCase, MyBaseForm callingForm)
{
CreateMultiReport(userLaen, arnIDs, ardIDs, callingForm);
}
private static void CreateMultiReport(int userLaen, int[] arnIDs, int[]
ardIDs, MyBaseForm callingForm)
{
object[] agOb = new object[4];
agOb[0] = userLaen;
agOb[1] = arnIDs;
agOb[2] = ardIDs;
agOb[3] = callingForm;
Thread t = new Thread(ReportGenerationForm.StartProcessingReports);
t.SetApartmentState(ApartmentState.STA);
t.IsBackground = true;
ReportGenerationForm.paramObjects = agOb;
t.Start();
}
////////////////////////////////////////////////////////////////////////
// Code in the child thread
// An exception might occur here, that should be pushed up to the main
// UI thread, for nomal display. This is a Form class instance.
////////////////////////////////////////////////////////////////////////
// I've tried to declare this in the main form gui, but no difference.
public delegate void ShowErrorMessage(string text);
public static void StartProcessingReports()
{
ReportGenerationForm frm = new
ReportGenerationForm((int)paramObjects[0],
paramObjects[1] as int[], paramObjects[2] as int[], paramObjects[3]
as MyBaseForm, true, true, true);
IntPtr handle = frm.Handle;
frm.ShowPrint();
}
private void ShowPrint()
{
try
{
ShowDialog();
TopMost = true;
BringToFront();
}
catch (Exception ex)
{
// I've tried lots of different things here, for example calling
Invoke on
// the delegate, calling invoke on the calling form etc etc, but no
use.
ShowErrorMessage d = new ShowErrorMessage((_callingForm as
XXX.YYY.ReportMainthreadForm).ShowThreadError);
IntPtr handle = this.Handle;
this.Invoke(d, new string[] { ex.Message });
}
}
regards
Carl
Jon Skeet [C# MVP] - 12 Mar 2008 16:28 GMT
> I'm unable to create such short example
Why? What happened when you tried?
> but I've tried to copy/paste the
> parts of where the threading problem occurs. There are only three classes
> involved, I've added comments to describe what I've tried to do.
Well, one thing I notice is that you're calling ShowDialog(),
TopMost=true, and BringToFront() from within the worker thread.
You shouldn't show a UI from a different thread than the one which
created it. That could well be part of the problem. The usual idea with
worker threads is that *non*-UI work is done in the worker thread, and
all UI updates etc are passed by to the UI thread.

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk