首页 > 解决方案 > 在当前进程中创建新线程时,有没有办法处理该事件?

问题描述

我希望能够检测到何时创建了一个新线程,例如Task.Run,如果可能的话,在它关闭时进行处理。

我知道可以通过你的进程处理当前线程Process.GetCurrentProcess().Threads,这有点有用。从我不知道它是在哪里创建的角度来看,我想要的是在新线程开始执行时处理它。

一些背景

正如有人问的那样,我在这里为我遇到的实际问题提供了一些细节,因为也许我正在寻找最不理想的解决方案。

我正在开发一个具有多个屏幕的大型系统,每个系统都有一堆控件,其中一些是自定义的。最近,团队逐渐采用异步/等待模式,并且锁定 UI 直到任务完成的问题已经上升。我们在我们的基本表单中创建了一个加载面板,公开了一个隐藏和显示方法,以供此基本表单的实现调用。这里的问题是返回到所有已经实现的表单,并在整个代码中调用这些方法,尤其是异步事件。在这里我想知道是否有一个更简单的解决方案可以适用于过去的实现并消除在事件之间调用方法的需要。

我们今天所做的事情大致如下:

public class BaseForm {
    public ShowPanel(){
        ...
    }

    public HidePanel(){
        ...
    }
}

public class FormImplementation : BaseForm {
    private async void OnEventAsync(object sender, EventArgs e){
        ShowPanel();
        // await stuff
        HidePanel();
    }
}

我发现手动将这些调用放在事件处理程序周围非常麻烦。我会做一些元编程空手道,但我在 C# 中没有经验。

标签: c#multithreadingwinforms

解决方案


也许我正在寻找最不理想的解决方案。

检查线程绝对是一种不正确的方法。一方面,async不使用线程,所以这种方法行不通。

我发现手动将这些调用放在事件处理程序周围非常麻烦。我会做一些元编程空手道,但我在 C# 中没有经验。

元编程是一种选择,也是一种相当不错的选择。PostSharp 和 Fody 都备受推崇。“在这些方法的开头和结尾做一些事情”是该领域的一个常见问题,而元编程是一个明确的选择。我认为你真正想要的是这样的:

public class BaseForm {
    public ShowPanel() {
        ...
    }

    public HidePanel() {
        ...
    }
}

public class FormImplementation : BaseForm {
    private async void OnEventAsync(object sender, EventArgs e) {
        ShowPanel();
        try { ... }
        finally { HidePanel(); }
    }
}

您可以通过使用一次性的,例如(使用我的 Nito.Disposables 库)和 C# 8 using 声明来最小化代码更改:

public class BaseForm {
    public IDisposable ShowPanel() {
        ...
        return new AnonymousDisposable(HidePanel);
    }

    private void HidePanel() {
        ...
    }
}

public class FormImplementation : BaseForm {
    private async void OnEventAsync(object sender, EventArgs e) {
        using var _ = ShowPanel();
        ...
    }
}

还有其他选择,例如将返回类型更改OnEventAsync为 be Task,但我认为这需要更多的代码更改,而不仅仅是执行上述操作。


推荐阅读