如何在C#中排队一个函数以被主线程调用?

3

我找到了很多关于如何在UI线程上调用函数的资源,但是我的一些逻辑只允许从主线程运行。有没有办法获取主线程上的调度程序并在其上调用?


6
任何合理的程序都应该将UI线程作为主线程。 - Servy
1
只有当主线程正在运行可以将委托发布到它上面的东西(例如消息循环)时,才能这样做。 - SLaks
1
你的主线程结构是怎样的?在你想要调用函数的时候,它正在做什么? - Amit
1
将来某个时候发生这件事,可以吗? - Amit
1
@Psymunn 与其创建一个新线程作为 UI 线程然后让主线程去做其他工作,为什么不把主线程作为 UI 线程,并让你创建的其他线程去处理主线程原来的工作呢? - Servy
显示剩余6条评论
3个回答

6
“调度器”是特定于某个 UI 框架(这里是 WPF)的概念。没有可以用来针对任何线程进行目标化的调度器。想象一下以下线程:
while (true) Console.WriteLine("x");

你要如何在那个线程上调用一些内容呢?那是不可能的,因为该线程正在忙于执行其他任务,它不愿配合。

我有点怀疑你是否需要在“主线程”上调用某些内容。但我会按照字面意思回答这个问题。你需要让主线程配合并接受来自其他线程的工作。也许可以使用 Action 队列或布尔标志告诉该线程执行特定操作。


谢谢。我会检查API,看看是否有一些静态队列可以访问,以便将任务排队到主线程。我知道这似乎有点奇怪,但确实是要求。 - Psymunn

1
你可以使用信号和数据结构的组合。定义一个变量来保存所需函数调用的详细信息(可能是具有参数的结构体),并让主线程定期测试是否需要调用。确保锁定必要的对象以处理多线程问题。你还可以拥有一个信号对象,并使发起者在其上Monitor.Wait,当函数完成时,主线程将发出信号。

0

编辑:OP提问的程序确实有单独的UI和主线程...

您可以随时使用以下方法创建新的线程/任务:

        tokenSource = new CancellationTokenSource();
        token = tokenSource.Token;

        Task.Factory.StartNew(() =>
        {
            doSomeWork();
        }, token);

令牌用于取消任务。如果出现问题或任务挂起,您可以取消它。您可能已经阅读了有关TPL库的信息,但如果没有,请查看并确定它是否适用于您想要执行的操作。

为了使我的答案更完整,我想添加这个...我不确定这在您的情况下是否有效,但在正常情况下,您会像这样更新或处理主线程中的对象。

    private void doSomeWork()
    {
        // do work here -->

        if (someObject.InvokeRequired)
        {
            someObject.BeginInvoke((Action)delegate() { someObject.Property = someValue; });
        }
        else
        {
            someObject.Property = someValue;
        }
    }

很遗憾,我无法控制架构。UI线程被命名为WPF线程,并从主线程启动(该线程具有入口点public static void Main(string[] args))。 - Psymunn
1
我能理解你的痛苦...很抱歉我没有提供更多的帮助。祝你的项目好运。 - waltmagic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接