I have a question.
I have a report that the load time is different I want show wait time to user , I think should use the Multi Thread but I not know how works it.

I need a bit more information about what you are trying to do before I can be much help.

To use multithreading have a look at delegates and the BeginInvoke() method. There is lots of information available about multi threading and worker threads out there.

I have a report that for first time take 10 sec to load and for next time take 4 sec Now I want to show user wait form.

Do you just want to show a marquee while the report is generating? And what part of generating the report takes so much time? The data selection? Here is one example:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting.Messaging;

namespace daniweb.progress3
  public partial class frmMain : Form
    const int SIMULATED_DELAY = 5;
    private frmProgress frm;

    public frmMain()

    private void buttonRunReport_Click(object sender, EventArgs e)
      //runs on gui thread
      frm = new frmProgress();

      DateTime dtStart = DateTime.Today.AddDays(-3);
      DateTime dtEnd = DateTime.Today.AddDays(+5);
      bool simulateError = false;

      new Func<DateTime, DateTime, bool, DataTable>(RunReport).BeginInvoke(dtStart, dtEnd, simulateError, new AsyncCallback(RunReportCallback), null);

    private void ShowReport(DataTable dt)
      //Runs on gui thread. This is where you show your report
      MessageBox.Show(string.Format("Your report is ready with {0:F0} records!", dt.Rows.Count));

    private DataTable RunReport(DateTime dtStart, DateTime dtEnd, bool SimulateError)
      //runs on another thread

      //select * from someTable where date >= dtStart and date <= dtEnd;
      DataTable dt = new DataTable();
      dt.Columns.Add(new DataColumn("Col1", typeof(string)));
      for (int i1 = 0; i1 <= 3; i1++)
        DataRow row = dt.NewRow();
        row["Col1"] = Guid.NewGuid().ToString();
      System.Threading.Thread.Sleep(1000 * SIMULATED_DELAY);
      return dt;

    private void RunReportCallback(IAsyncResult ar)
      //runs on another thread
      AsyncResult result = (AsyncResult)ar;
      Func<DateTime, DateTime, bool, DataTable> del = (Func<DateTime, DateTime, bool, DataTable>)result.AsyncDelegate;
        DataTable dt = del.EndInvoke(ar);
        this.Invoke(new MethodInvoker(
            if (frm != null)
              frm = null;
      catch (Exception ex)
        MessageBox.Show("ERROR: " + Environment.NewLine + ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);


Project attached.

I forgot to hook up the simulateError property but i'm sure you can figure that one out ;)

Edited 7 Years Ago by sknake: n/a

I like the use of the generic delegate! I hadn't thought about using them like that, it's much tidier than creating a custom delegate every time.

Edited 7 Years Ago by privatevoid: n/a

First thank you , Secondly your code is static for example you definition show wait from 10 sec but i want to show wait form until report in the first form Be loaded and I not know How long does it take

It is static to intentionally cause a delay to simulate your condition. The progress form will keep showing a "working" progress bar until the operation completes regardless of the actual time required.

This article has been dead for over six months. Start a new discussion instead.