Carl
Wed Mar 12 10:06:44 CDT 2008
"Jon Skeet [C# MVP]" <skeet@pobox.com> wrote in message
news:MPG.2241e56285b201c8adf@msnews.microsoft.com...
>
> 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