C# 如何从构造函数调用异步方法?

C# 如何从构造函数调用异步方法?,c#,winforms,constructor,async-await,C#,Winforms,Constructor,Async Await,我需要从我的Form1构造函数调用async方法。因为构造函数不能有返回类型,所以我不能添加异步void。我读到可以是async,但我需要从构造函数调用非静态的方法,比如InitializeComponent()(因为它是表单的构造函数) 课程为: public partial class Form1 : Form { InitializeComponent(); //some stuff await myMethod(); } 我也读过一篇文章,但我仍然不知道如何实现

我需要从我的
Form1
构造函数调用
async
方法。因为构造函数不能有返回类型,所以我不能添加
异步void
。我读到可以是
async
,但我需要从构造函数调用非
静态的方法,比如
InitializeComponent()
(因为它是表单的构造函数)

课程为:

public partial class Form1 : Form
{
    InitializeComponent();
    //some stuff
    await myMethod();
}

我也读过一篇文章,但我仍然不知道如何实现它(在我的例子中),因为该方法仍然需要使用
async

不要在构造函数中执行此操作,而是在窗口的已加载事件中执行。
您可以将加载的eventhandler标记为async。

您可以使用返回表单实例的静态方法

public class TestForm : Form
{
    private TestForm()
    {
    }

    public static async Task<TestForm> Create()
    {
        await myMethod();
        return new TestForm();
    }
}
公共类TestForm:Form
{
私有TestForm()
{
}
公共静态异步任务Create()
{
等待我的方法();
返回新的TestForm();
}
}

任务。运行(async()=>等待您的asynchmethod())

我的示例是从页面构造函数调用学生详细信息

1-导航页面的调用

    void Handle_ItemTapped(object sender, Xamarin.Forms.ItemTappedEventArgs e)
    {
        Student _student = (Student)e.Item;
        Navigation.PushAsync(new Student_Details(_student.ID));

    }
2-详情页

public partial class Student_Details : ContentPage
{
    public Student_Details(int id)
    {
        InitializeComponent();
        Task.Run(async () => await getStudent(id));
    }

    public async Task<int> getStudent(int id)
    {
        Student _student;
        SQLiteDatabase db = new SQLiteDatabase();
        _student = await db.getStudent(id);
        return 0;
    }
}
public部分班学生详细信息:ContentPage
{
公共学生详细信息(内部id)
{
初始化组件();
运行(async()=>await-getStudent(id));
}
公共异步任务getStudent(int id)
{
学生(学生),;
SQLiteDatabase db=新的SQLiteDatabase();
_学生=等待db.getStudent(id);
返回0;
}
}

虽然一般建议您通常不应该在构造函数中执行此操作,但您可以执行以下操作,我在应用程序(如控制台应用程序)中使用了这些操作,其中我需要调用一些现有的异步代码:

DetailsModel details = null; // holds the eventual result
var apiTask = new Task(() => details = MyService.GetDetailsAsync(id).Result); // creates the task with the call on another thread
apiTask.Start(); // starts the task - important, or you'll spin forever
Task.WaitAll(apiTask); // waits for it to complete

Philip是正确的,如果你可以避免在构造函数中这样做,你应该这样做。

我接受了答案,但我有一个问题。要调用
Create()
我不应该这样做
await Create()
如果是这样,我确实需要将构造函数标记为
async
不是吗?@Jack Yes您可以将其称为
await TestForm.Create()
,但构造函数不必是异步的,请清楚地阅读Stephen的内容。仅供参考,那里的链接实际上似乎在调用异步静态工厂方法,作为使用异步的静态构造函数的替代方法。在这篇文章中,它说静态构造函数不能是异步的。在堆栈溢出方面,最好的做法是添加一个解释,说明为什么您的解决方案应该工作。要了解更多信息,请阅读。您不就是以一个
异步void WindowLoaded()
结束吗?我们不应该避免异步无效吗?仅从构造函数调用
私有异步void MyMethodAsync()
有什么区别?事件处理程序是一种特殊情况。