小编Zer*_*er0的帖子

使用async/await时如何更好地处理已处理的控件

考虑在UI线程上运行的此代码:

dividends = await Database.GetDividends();
if (IsDisposed)
    return;
//Do expensive UI work here
earnings = await Database.GetEarnings();
if (IsDisposed)
    return;
//Do expensive UI work here
//etc...
Run Code Online (Sandbox Code Playgroud)

请注意,每次await我也检查IsDisposed.这是必要的,因为说我await长时间跑步Task.同时,用户在完成之前关闭表单.在Task将完成并运行一个试图访问已释放的窗体上的控件延续.发生异常.

有没有更好的方法来处理这个或简化这种模式?我await在UI代码中使用自由,IsDisposed如果我忘记的话,每次都要检查它并且容易出错.

编辑:

有一些提议的解决方案不符合要求,因为它们会改变功能.

  • 防止表单关闭,直到后台任务完成

这会让用户感到沮丧.而且它仍然允许发生可能昂贵的GUI工作,这是浪费时间,伤害性能并且不再相关.在我几乎总是在做背景工作的情况下,这可以防止表格在很长一段时间内关闭.

  • 完成所有任务后,隐藏表单并关闭它

这具有阻止表单关闭的所有问题,除非不会使用户感到沮丧.执行昂贵GUI工作的延续仍将继续.它还增加了所有任务完成时的跟踪复杂性,然后在隐藏时关闭表单.

  • 使用a CancellationTokenSource在表单关闭时取消所有任务

这甚至没有解决问题.事实上,我已经这样做了(浪费背景资源也没有意义).这不是解决方案,因为我仍然需要检查IsDisposed由于隐式竞争条件.以下代码演示了竞争条件.

public partial class NotMainForm : Form
{
    private readonly CancellationTokenSource tokenSource = new CancellationTokenSource();

    public NotMainForm()
    {
        InitializeComponent();
        FormClosing += (sender, args) => tokenSource.Cancel();
        Load += …
Run Code Online (Sandbox Code Playgroud)

c# asynchronous winforms async-await

13
推荐指数
1
解决办法
1119
查看次数

托管与非托管类型

我正在阅读一篇关于如何sizeof在 C# 中使用运算符的文章

他们说:“用于获取非托管类型的大小(以字节为单位)。”

我知道托管和非托管代码之间的区别。但我的理解是,我用 C# 编写的所有代码(包括所有预定义和用户定义类型)都由 CLR 管理。那么他们所说的“非托管类型”是什么意思?

c# unmanaged managed sizeof

11
推荐指数
1
解决办法
1808
查看次数

标签 统计

c# ×2

async-await ×1

asynchronous ×1

managed ×1

sizeof ×1

unmanaged ×1

winforms ×1