c# - 如何在来自 Web API 的窗体加载事件上预填充 Windows 窗体控件?

标签 c# multithreading winforms asp.net-web-api2

我有一个包含两个项目的解决方案:一个是 Web API,另一个是 Windows 窗体应用程序。在 Windows 窗体应用程序中,我发送一个获取请求来检索一些数据。所以我有这样的方法:

private async Task StartFillingEvent()
{
    var path = "api/Windows/GetEventNames/";
    List<EventItemDto> events = null;
    HttpResponseMessage response = await client.GetAsync(path);
    if (response.IsSuccessStatusCode)
    {
        events = await response.Content.ReadAsAsync<List<EventItemDto>>();
        var eventList = (from c in events
                            select new ListItemVm<Guid>()
                            {
                                Id = c.EventId,
                                Name = c.Title
                            }).ToList();

        eventsDrp.FillDropDownList<Guid>("Please choose one", eventList, null);
    }
}

获取我的数据并在 form_Load 中调用此方法:

private void frmOnlineBadge_Load(object sender, EventArgs e)
{
    StartFillingEvent().Wait();
}

我跟踪我的应用程序,它转到 Web API 并将数据检索到 Windows 窗体应用程序。但是应用程序在 if 语句中休眠。我对多线程一无所知。我的目标是与 Web API 交互。我用谷歌搜索,发现很多教程都是关于 Windows 控制台应用程序的,而不是关于 Windows 窗体的。我用控制台应用程序检查了我的程序,但我必须使用 Forms 应用程序中的控件。

我如何管理此数据检索?

最佳答案

等待 async 方法时要小心。由于它与您执行 Wait 时在同一个线程上运行,因此您会遇到死锁。 async/await 多任务处理是协作的。这意味着 await 正在等待调用者返回控制权。如果调用者现在调用 Wait,它将永远不会返回控制权。

解决方案是在任务中运行您的辅助方法:

private void frmOnlineBadge_Load(object sender, EventArgs e)
{
    Task.Run(() => StartFillingEvent()).Wait();
}

这会将任务包装到代理中,代理将作为真正的任务运行。因此,您必须修改填充组合框的部分:

Action fillAction = delegate() {
    eventsDrp.FillDropDownList<Guid>("Please choose one", eventList, null);
};
dropDownList.BeginInvoke(fillAction);

原因是因为您现在在后台运行您的操作,您必须确保在 UI 线程中执行访问 UI 的部分。这是通过 Control.BeginInvoke 完成的。

更新:

我最初写道你应该使用 Control.Invoke。这是错误的,因为这个方法会阻塞,直到 UI 线程执行完 Action 为止。由于 UI 线程正在等待,这也会导致死锁。所以你必须使用 BeginInvoke

关于c# - 如何在来自 Web API 的窗体加载事件上预填充 Windows 窗体控件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41101140/

相关文章:

c# - 在 C# 中使用 ADO.NET 进行登录身份验证

c# - 公开课 - "is inaccessible due to its protection level. Only public types can be processed."

winforms - 当 Dock=Fill 时设置除 0,0 以外的位置

c# - HTTP 错误 503。服务在 IIS 中不可用?

C# MVC 3 : Prevent magic string in property attribute

c# - 无法找到接受类型 'Value' 的第一个参数的 '' 的定义

java - 使用线程输入

java - 一个线程只有一个实例

multithreading - Haskell 中的生产者和消费者问题?

c# - 在 .NET 7 和 WinForms 应用程序中使用 SqlDependency