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.

Dani AI

Generated

A simple, robust pattern is: run the report on a background thread, show an indeterminate progress UI while it runs, then close the UI and display results on the UI thread when the work completes. and pointed you toward doing the work off the UI thread and provided a working simulated example; the next step is to adopt a pattern that is reliable for real queries, handles errors and cancellation, and doesn't hard-code any wait time.

A modern, easy approach (if you can use .NET 4.5+) is to start the long work with Task.Run, show a modeless wait form, await the task, then close the form in finally so it always goes away even on error. Example flow:

private async void btnRun_Click(object sender, EventArgs e)
{
  var wait = new WaitForm();
  wait.Show(this);            // show modeless so UI thread is not blocked
  try
  {
    var result = await Task.Run(() => GenerateReport(...)); // background
    ShowReport(result);       // runs on UI thread after await
  }
  catch (Exception ex) { /* show error to user */ }
  finally { wait.Close(); }
}

If you must support older frameworks, use BackgroundWorker (DoWork / RunWorkerCompleted / ReportProgress) so you get progress and completion callbacks on the UI thread. See the BackgroundWorker docs for details: BackgroundWorker. For async/await guidance see: async/await guide.

Practical tips: create the wait form on the UI thread (so Close()/controls are safe), disable the Run button to prevent reentrancy, handle exceptions from the background operation, add cancellation (CancellationToken) if the user should be able to cancel, and use progress reporting (IProgress<T>) if you can measure progress. For first-run slowness consider caching or pre-warming the query so subsequent shows are fast.

Recommended Answers

All 10 Replies

hi
Please help me .

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.

Hi
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.

You should run whatever is taking a long time on a seperate thread, have a look at this tutorial:

()_and_EndInvoke()_Methods

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()
    {
      InitializeComponent();
    }

    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);
      frm.ShowDialog();
    }

    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();
        dt.Rows.Add(row);
      }
      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;
      try
      {
        DataTable dt = del.EndInvoke(ar);
        this.Invoke(new MethodInvoker(
          delegate()
          {
            if (frm != null)
            {
              frm.Close();
              frm.Dispose();
              frm = null;
            }
            ShowReport(dt);
          }));
      }
      catch (Exception ex)
      {
        MessageBox.Show("ERROR: " + Environment.NewLine + ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
    }
    

  }
}

Project attached.

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

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.

Every Thank you
I will review the code you soon

now

hi
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.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.