gpt4 book ai didi

c# - 异步/等待 Windows 窗体应用程序

转载 作者:行者123 更新时间:2023-11-30 21:55:50 25 4
gpt4 key购买 nike

我正在尝试在我的应用程序中学习和实现 async/await 关键字。我正在使用 API 获取数据,然后将它们显示在我的表单上。当我尝试从控制台应用程序调用方法时没有问题。但是,如果我从 Form_Shown 事件调用我的异步方法,也没有异常,但方法不起作用。

所以我在 Form_Shown 事件上调用我的 RefreshOrLoadDataToCache() 方法。

private async void LogTimeReport_Shown(object sender, EventArgs e)
{
// Some syncronous operations

RefreshOrLoadDataToCache(); // Async methods in it

// Some syncronous operations
}

在我的这个方法中创建了一个任务并等待它。

private async void RefreshOrLoadDataToCache()
{
if (IsNeededToCallAPI())
{
var taskForTimeEntries = LoadTimeEntriesTemp();
Task.WhenAll(taskForTimeEntries);

DataTable dtTimeEntriesTemp = taskForTimeEntries.Result;
DataTable dtEventsTemp = LoadEventsTemp();

dtTimeEntriesTemp.Merge(dtEventsTemp);
}
else
BindGridViews();
}

这是我的异步方法。

 private async Task<DataTable> LoadTimeEntriesTemp()
{
TimeEntryHandler timeHandler = new TimeEntryHandler();

TimeEntryResponse response = await timeHandler.GetTimeEntries();

DataTable dt = DatatableHelper.ToDataTable<TimeEntry>(response.TimeEntries);

foreach (DataRow drow in dt.Rows)
{
// Some operations on DataTable
}
return dt;
}

在这种方法中,我连接到 API 并获得结果。我认为我的问题是关于这种方法。因为当我从控制台应用程序调用此方法时,它会返回数据。但是从表单申请它等待很长时间但没有结果或异常。

private async Task<TimeEntryResponse> GetTimeEntries()
{
using (var client = new AuthorizedHttpClient(_client))
{
var data = await client.GetAsync<TimeEntryResponse>(parameters);

if (data.StatusCode == HttpStatusCode.OK)
{
var response = (TimeEntryResponse)data.ContentObj;
response.Pages = int.Parse(data.Headers.GetValues("X-Pages").First());
response.Page = int.Parse(data.Headers.GetValues("X-Page").First());
response.TotalRecords = int.Parse(data.Headers.GetValues("X-Records").First());
return response;
}
return new TimeEntryResponse() { TimeEntries = null, STATUS = "ERROR" };
}
}

我认为 Windows 窗体上的异步调用缺少一些东西。如何修复我的代码?

最佳答案

你的代码有几个问题

  1. 您将一个方法标记为async,但您不等待其中的操作。您目前这样做是因为 RefreshOrLoadasync void。它实际上需要是 async Task,其中底层返回的任务是正在进行的异步操作。然后,返回的 Task 应该等待:

    private async void LogTimeReport_Shown(object sender, EventArgs e)
    {
    // Some syncronous operations

    await RefreshOrLoadDataToCache(); // Async methods in it

    // Some syncronous operations
    }
  2. RefreshOrLoad 是一种异步方法。您使用 Task.WhenAll,它用于异步等待多个任务,但您也不需要 await。然后,您调用 .Resultwhich causes your code to effectively deadlock .所需要做的就是等待任务从 LoadTimeEntriesTemp 返回:

    private async Task RefreshOrLoadDataToCache()
    {
    if (IsNeededToCallAPI())
    {
    DataTable dtTimeEntriesTemp = await LoadTimeEntriesTemp();
    DataTable dtEventsTemp = LoadEventsTemp();

    dtTimeEntriesTemp.Merge(dtEventsTemp);
    }
    else
    BindGridViews();
    }

    我还注意到您应该将 *Async 后缀与您的异步方法一起使用。

修复这些问题时,您会发现代码的行为符合预期,一直是异步的。

关于c# - 异步/等待 Windows 窗体应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31892043/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com