c# - WinForms 异步加载任务未完成
问题描述
我正在使用 .NET Framework v4.7.2。我有下面原始代码的简化版本。
在我最初的问题中,处理程序过早结束Form_Load()
,所以我决定将Form_Load()
处理程序中的所有内容包装在 aTask
中,然后在Form_Show()
处理程序中(在. 我关心的数据是,即将出来的。 Form_Load()
Task
stringArray
null
显然,我更愿意弄清楚为什么 Form_Load()
会过早结束,但我没有运气。
我知道在这里挣扎,可能错过了一些基本概念。我觉得如果我能理解为什么stringArray
是null
,我就会明白为什么我的原作Form_Load()
提前结束了。的财产formLoadTask
怎么可能是这样?Status
RanToCompletion
stringArray
null
请记住这是真实代码的简化版本。
谢谢
interface IRetriever
{
Task<String[]> GetStringArray();
}
class Retriever : IRetriever
{
public async Task<string[]> GetStringArray()
{
return await Task.FromResult(new string[] { "More", "Larry", "Curly", });
}
}
static class Director
{
internal static async Task<IRetriever> CreateRetriever()
{
return await Task<IRetriever>.Factory.StartNew(() =>
{
// Simulate some I/O bound waiting...
Thread.Sleep(5000);
return new Retriever();
});
}
}
public partial class Form1 : Form
{
private static String[] stringArray;
private static IRetriever retriever;
internal Task formLoadTask;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
formLoadTask = Task.Factory.StartNew(async () =>
{
retriever = await Director.CreateRetriever();
stringArray = await retriever.GetStringArray();
});
}
private void Form1_Shown(object sender, EventArgs e)
{
// I know I am tying up the UI thread here. This is just an example.
formLoadTask.Wait();
// At this point the formLoadTask is finished, so shouldn't the stringArray be populated?
// The next line throws a NullReferenceException because stringArray is null.
// Why??
System.Diagnostics.Debug.WriteLine(stringArray.Length);
}
}
解决方案
StartNew
无法识别您的异步委托。它把它当作一个Func<Task>
没有人最终等待的东西。您存储formLoadTask
的任务只是启动任务的任务,而不是任务本身。
您可以解开任务或使用更现代的Task.Run
,它可以正确处理异步委托。
formLoadTask = Task.Factory.StartNew(async () =>
{
retriever = await Director.CreateRetriever();
stringArray = await retriever.GetStringArray();
}).Unwrap();
或(首选):
formLoadTask = Task.Run(async () =>
{
retriever = await Director.CreateRetriever();
stringArray = await retriever.GetStringArray();
});
推荐阅读
- oracle - 按日期间隔检索多列分组
- javascript - 多个 hiddenInput 字段 intl-tel-input 包
- python - 在 Python 上使用 fredapi 导入系列
- html - HTML 视频变为绿色,无法播放。我该如何解决?
- python - Discord.py on_member_join 事件
- node.js - 多个上传提供商 Strapi
- javascript - 如何在页面更改时滚动到向导表单的顶部
- java - 如何在包含特定字符串的文本文件中查找行并用新字符串替换每一行?
- react-native - ReactNative - 警告:无法从不同组件的函数体内更新组件
- wordpress - 功能中的wordpress自定义插件enqueue_script不起作用