Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
658 views
in Technique[技术] by (71.8m points)

c# - Load data asynchronously into DataTable in Windows Forms

I'm modifying the data access layer of an old WinForms/ADO app to get Salesforce objects using soql over the asynchronous developerforce rest api. The following approach generally works, except that one of my thirteen tables routines never returns from the AddMyTableRow (System.Data.DataRowCollection.Add()) method:

public void LoadData() {
    var tasks = new List<Task<int>> {
        GetObject1Async(),
        GetObject2Async(),...
        GetObject13Async()
    };
    Task.WaitAll(tasks.ToArray());
    //do some postprocessing now that I have all the data
}

async Task<int> GetObject1Async(){
    var response = await cnx.QueryAsync<dynamic>("SELECT foo FROM bar").ConfigureAwait(false);
    foreach (var rec in response.Records){
        var row = MyDataSet.MyTable.NewMyTableRow();
        row.Name = rec.Name; ...
        MyDataSet.MyTable.AddMyTableRow(row); //<== Sometimes this never returns
    }
    return MyDataSet.MyTable.Count;
}

Is this even the right approach?

I've found that if I comment out the whole await cnx.Query... line and just call AddMyTableRow(dummyData) it works. I feel like there is some kind of async /threading / context something going on, but since its not generating any kind of error or exception I don't know what to go on.

Cheers, Jeff

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can have an async method which returns Task<DataTable> and then in async form Load event handler or in the async method which you want to perform data-binding, await call it, then use the result to bind to the grid.

Example

public async Task<DataTable> GetDataAsync(string command, string connection)
{
    var dt = new DataTable();
    using (var da = new SqlDataAdapter(command, connection))
        await Task.Run(() => da.Fill(dt));
    return dt;
}

private async void Form1_Load(object sender, EventArgs e)
{
    var command = @"SELECT * FROM Category";
    var connection = @"Your Connection String";
    var data = await GetDataAsync(command, connection);
    this.dataGridView1.DataSource = data;
}

To see how you can show a loading animation over the DataGridView, take a look at this post.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...