0

I've a form that runs a query from a DataGridView on a button click. The below code works how I expect it to;

  1. Opens a form that says "Please Wait while query runs"
  2. Runs query
  3. Closes form when loaded and then fill the DataGridView with the data.

I have added a picturebox with simple gif - purely for the UI and the user to see it is working. But the gif doesn't actually spin - just shows as a picture. Testing it, if I run it on a form on its own it is fine, I can only hazard a guess that the query running is stopping it from working how it should.

        PleaseWaitForm pleaseWait = new PleaseWaitForm();
        try
        {
            pleaseWait.Show();
            Application.DoEvents();

            this.singleCenTableAdapter.Fill(this.singleCenData.SingleCenTable, ((System.DateTime)(System.Convert.ChangeType(txtBookFrom.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtBookTo.Text, typeof(System.DateTime)))));
            int RowC = singleCenTableDataGridView.RowCount;
            pleaseWait.Close();
            if (RowC == 0)
            {
                MessageBox.Show(GlobVar.NoResults, "", MessageBoxButtons.OK, MessageBoxIcon.Hand);
            }
            pleaseWait.Close();
        }
        catch (System.Exception exc)
        {
            GlobVar.vid.Open();
            var LogName = GlobVar.LoginName.ExecuteScalar();
            GlobVar.vid.Close();
            MessageBox.Show
                (
                "An error has occured " + LogNam + ". Please try again. \n\n" +
                exc.Message, "An error has occured", MessageBoxButtons.OK, MessageBoxIcon.Warning
                );
        }
        finally
        {
            pleaseWait.Close();
        }

The "Please Wait" form is just a label & picture so there is nothing but the Initalize in there at the minute ;

    public PleaseWaitForm()
    {
        InitializeComponent();
    }

Does anybody have any ideas on how to tackle this to make it work correct? Or anything particular that I am doing wrong? I know for the most part I might get a bit of stick for using Application.DoEvents() anyway, but any help is appreciated!

M. Adeel Khalid
  • 1,786
  • 2
  • 21
  • 24
Zoltan
  • 93
  • 7
  • 1
    You can use Thread or BackgroundWorker to achieve this. – Rajendra Mar 21 '17 at 17:23
  • You can use `async` and `await` to keep your UI responsive. See [Asynchronous Programming with async and await (C#)](https://msdn.microsoft.com/en-us/library/mt674882.aspx). Alternatively, you can use [Task-based Asynchronous Programming](https://msdn.microsoft.com/en-us/library/dd537609(v=vs.110).aspx), but `async` and `await` are simpler and should be sufficient enough for your problem. – PJvG Mar 22 '17 at 10:20
  • @Rajendra `async`, `await` and TPL are designed to replace `Thread` and `BackgroundWorker`. – PJvG Mar 22 '17 at 10:24

2 Answers2

2

I read in your comment that you use .NET 4.0 and therefore can not use await and async with Task<>.

Before .NET 4.5, you can use Thread or BackgroundWorker to achieve this,
refer to the following example of BackgroundWorker:

Background Worker loading screen in Winforms

Your current code is running in synchronously, you are expecting it to work in asynchronously.

Community
  • 1
  • 1
Rajendra
  • 191
  • 1
  • 13
0

You need async and await to keep your UI responsive.

First make the method this code is in async as follows:

private async void Method()
{
    ...
}

Next place the following code in a new method:

this.singleCenTableAdapter.Fill(this.singleCenData.SingleCenTable, ((System.DateTime)(System.Convert.ChangeType(txtBookFrom.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtBookTo.Text, typeof(System.DateTime)))));
int RowC = singleCenTableDataGridView.RowCount;

For example:

private async Task<int> FillAndGetRowCount( ... ) // add parameters if needed
{
    this.singleCenTableAdapter.Fill(this.singleCenData.SingleCenTable, ((System.DateTime)(System.Convert.ChangeType(txtBookFrom.Text, typeof(System.DateTime)))), ((System.DateTime)(System.Convert.ChangeType(txtBookTo.Text, typeof(System.DateTime)))));
    return singleCenTableDataGridView.RowCount;
}

Finally, change your try block to:

try
{
    pleaseWait.Show();
    Application.DoEvents();

    int RowC = await FillAndGetRowCount( ... );
    pleaseWait.Close();
    if (RowC == 0)
    {
        MessageBox.Show(GlobVar.NoResults, "", MessageBoxButtons.OK, MessageBoxIcon.Hand);
    }
}
PJvG
  • 1,310
  • 3
  • 16
  • 33
  • Hello - sorry for late responce been trying to do this for a while now, i just get tons of different errors with this. One being this every time ; 'Task' does not contain a definition for 'GetAwaiter' and no extension method 'GetAwaiter' accepting a first argument of type 'Task' could be found (are you missing a using directive or an assembly reference?) – Zoltan Mar 28 '17 at 14:01
  • @Zoltan Are you using .NET 4.5 or above? Or are you using an older version of .NET? My solution only works for .NET 4.5 and above. – PJvG Mar 28 '17 at 14:06
  • 1
    Ah!!!! I will create a test project on .NET 4.5 or above and test. I have had to lower the framework to .NET 4.0 as users only have this installed and not enough privilege by IT to allow them to install 4.5 or above – Zoltan Mar 28 '17 at 14:12
  • @Zoltan Perhaps using [Microsoft.Bcl.Async](https://www.nuget.org/packages/Microsoft.Bcl.Async/) NuGet package is also an option for you? Also see the following: http://stackoverflow.com/a/39662411/2541501 – PJvG Mar 28 '17 at 14:21
  • @Zoltan You can also just decide to use `Thread` or `BackgroundWorker` as @Rajendra suggested in [his answer](http://stackoverflow.com/questions/42933852/c-sharp-gif-not-loading/42934246#42934246) if you have to use .NET 4.0, since that was the way to do this sort of thing before .NET 4.5. – PJvG Mar 28 '17 at 14:22
  • It is sort of better! If i use pleaseWait.Show() its just as bad - no animation and loads. If i use pleaseWait.ShowDialog() I get the animation - but it does not load the data into the grid. – Zoltan Mar 28 '17 at 14:50
  • @Zoltan Perhaps update your question post with this new information or ask a new question (create a new question post), because extended discussions should be avoided in comments on Stack Overflow. – PJvG Mar 28 '17 at 15:01