在当前进程中创建新线程时,是否可以处理事件?

时间:2019-07-18 13:08:23

标签: c# multithreading winforms

我想能够检测何时创建新线程,例如Task.Run,并在可能的情况下在关闭时进行处理。

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

某些背景

根据要求,我在这里详细介绍了我所遇到的实际问题,因为也许我正在寻找最不理想的解决方案。

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

我们今天的工作大致是这样:

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

    public HidePanel(){
        ...
    }
}

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

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

1 个答案:

答案 0 :(得分:2)

  

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

检查线程绝对是不正确的方法。对于async doesn't use threads来说,这样的方法是行不通的。

  

我发现手动将这些调用放在事件处理程序周围非常麻烦。我会做一些元编程空手道,但是我在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(); }
    }
}

您可以通过将一次性代码(例如,使用my Nito.Disposables library)与C#8 using declaration结合使用,以最小化代码更改:

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的返回类型更改为Task,但我认为,除了上述操作之外,还需要更多代码更改。