C#表单在启动时加载组合框项

C#表单在启动时加载组合框项,c#,combobox,C#,Combobox,我有一个组合框,我想加载一个文本文件中存储的客户端电子邮件地址。使用loadComboEmail()读取文本文件并加载组合框。我在表单启动时调用loadComboEmail是否做了一些被认为是不好的做法?如果是这样的话,我如何正确地读取文本文件,然后将其加载到组合中,这样当表单加载时,它就有了必要的数据?不,这似乎是合法的。您不必担心,因为这是在WinForms中加载所有内容的方式。。。这将在短时间内阻塞UI线程,但由于您不打算加载大量的内容,因此您甚至不会注意到它 当您开始执行大量操作和大文件

我有一个组合框,我想加载一个文本文件中存储的客户端电子邮件地址。使用
loadComboEmail()
读取文本文件并加载
组合框。我在表单启动时调用
loadComboEmail
是否做了一些被认为是不好的做法?如果是这样的话,我如何正确地读取文本文件,然后将其加载到组合中,这样当表单加载时,它就有了必要的数据?

不,这似乎是合法的。您不必担心,因为这是在
WinForms
中加载所有内容的方式。。。这将在短时间内阻塞
UI
线程,但由于您不打算加载大量的内容,因此您甚至不会注意到它

当您开始执行大量操作和大文件时,您应该考虑使用
后台工作人员
任务

无论如何,你也应该考虑使用下面的代码代替你的代码:

public Form1()
{
    InitializeComponent();
    loadComboEmail();
}

private void loadComboEmail()
{
    string path = Directory.GetCurrentDirectory();
    string build = (path + "\\" + "email.txt");
    string[] lines = System.IO.File.ReadAllLines(build);

    comboEmail.Items.AddRange(lines);
    comboEmail.SelectedIndex=0;
}
您可以使用:

private void loadComboEmail()
{
    string path = System.IO.Path.GetDirectoryName(Application.ExecutablePath); //seems to be the same to me, but is safer
    string build = System.IO.Path.Combine(path, "email.txt"); //much more safer then simple string addition
    string[] lines = System.IO.File.ReadAllLines(build);

    comboEmail.Items.AddRange(lines);
    comboEmail.SelectedIndex = 0;
}
为了更新UI线程,您可以在另一个线程上进行读取,当加载电子邮件列表时,只需更新它即可

 Task task = Task.Factory.StartNew(() =>
 {
    // Background work
    loadComboEmail();
 }).ContinueWith((t) => 
 {
    //If you need to execute something after the loading process.
 });

使用构造函数加载不被认为是不好的做法。阅读Hans Passant关于何时应该使用窗口加载事件的答案

尽管如评论中所说,您正在阻止UI线程。在构造函数中,不能使用关键字await。所以你必须“开火然后忘记”。使用
Load
事件时,可以使用
wait
但事件处理程序是
async void
。所以他们没有被等待,你仍然有'火和忘记'

Task.Factory.StartNew(() =>
        {
            // Background work - read the file
        }).ContinueWith((t) => {
            // Update UI thread here

        }, TaskScheduler.FromCurrentSynchronizationContext());

这很好,虽然您将阻止UI线程。如果您执行此异步操作以避免UI冻结,效果会更好。@MasihAkbari-您能告诉我如何在loadComboEmail()方法中实现异步吗?它将运行,但会给出以下警告:警告3此异步方法缺少“等待”运算符,并且将同步运行。考虑使用“Acess”操作符等待非阻塞API调用,或“等待任务.Run(…)”在后台线程上执行CPU绑定的工作。C:\用户\NEXUSTFECT\DATABOS\VisualStudio 2013 \项目\水晶消息\水晶消息\ Frim1.CCS 30 28水晶MeaseGracRT,一些不正确的编码。请用新样品再试一次。您现在仍然会收到一条警告,因为无法在构造函数内完成等待。另一个解决方案是使用Olaru Mircea@Martijn van Put所示的延续任务——我试过了。现在可以了。你有没有一篇文章,或者你在什么地方学到了这一切(任务,等待),我想自己去读和理解。很好,现在就可以了!当然可以,看看这里:。另外,o'Reilly有一本关于异步的好书:Quick question,我注意到有时候它会加载,但是combobox没有加载,我必须关闭并重新打开应用程序。有什么原因吗?@Nexusfactor没问题,我很高兴能帮助你。请将我的答案标记为已解决,如果我帮了你的话:我只是想知道,线程是一个需要我花一段时间才能理解的概念。鉴于我只是从一个文本文件中读取,并加载一些表单控件,在我的例子中使用异步不是很有必要吗?使用Martijn van给我的代码,它仍然说它将同步运行,所以使用他的正确?@Nexusfactor是正确的,因为你没有加载200 MB的文本并对其进行处理。因此,您现在不必担心和使用它。谢谢,非常感谢。
public Form1()
{
    InitializeComponent();
    loadComboEmail();
}

private async Task loadComboEmail()
{
    string path = Directory.GetCurrentDirectory();
    string build = (path + "\\" + "email.txt");
    string[] lines = await Task.Run(() => File.ReadAllLines(build));

    comboEmail.Items.AddRange(lines);
    comboEmail.SelectedIndex=0;
}