C# 控制线程(恢复/挂起)

2024-04-02

我正在尝试模拟(非常基本且简单的)操作系统进程管理器子系统,我有三个“进程”(工作人员)向控制台写入内容(这是一个示例):

    public class Message
    {
        public Message() { }
        public void Show()
        {
            while (true)
            {
                Console.WriteLine("Something");
                Thread.Sleep(100);
            }
        }
    }

每个工作线程都应该在不同的线程上运行。我现在就是这样做的: 我有一个 Process 类,它的构造函数接受 Action 委托并从中启动一个线程,暂停它.

public class Process
{
    Thread thrd;
    Action act;

    public Process(Action act)
    {
        this.act = act;

        thrd = new Thread(new ThreadStart(this.act));
        thrd.Start();
        thrd.Suspend();
    }

    public void Suspend()
    {
        thrd.Suspend();
    }

    public void Resume()
    {
        thrd.Resume();
    }
}

在这种状态下,它会在我的调度程序之前等待恢复它,给它一个运行时间片,然后再次挂起它。

        public void Scheduler()
        {
            while (true)
            {
                //ProcessQueue is just FIFO queue for processes
                //MainQueue is FIFO queue for ProcessQueue's
                ProcessQueue currentQueue = mainQueue.Dequeue();
                int count = currentQueue.Count;

                if (currentQueue.Count > 0)
                {
                    while (count > 0)
                    {
                        Process currentProcess = currentQueue.GetNext();

                        currentProcess.Resume();
                        //this is the time slice given to the process
                        Thread.Sleep(1000);
                        currentProcess.Suspend();

                        Console.WriteLine();
                        currentQueue.Add(currentProcess);

                        count--;
                    }
                }

                mainQueue.Enqueue(currentQueue);
            }
        }

问题是它不能始终如一地工作。在这种状态下它甚至根本不起作用,我必须在工作人员的 Show() 方法中的 WriteLine 之前添加 Thread.Sleep() ,就像这样。

        public void Show()
        {
            while (true)
            {
                Thread.Sleep(100); //Without this line code doesn't work
                Console.WriteLine("Something");
                Thread.Sleep(100);
            }
        }

我一直在尝试使用 ManualResetEvent 而不是挂起/恢复,它可以工作,但由于该事件是共享的,依赖它的所有线程都会同时唤醒,而我只需要一次激活一个特定线程。

如果有人可以帮助我弄清楚如何正常暂停/恢复任务/线程,那就太好了。 我正在做的是尝试模拟简单的抢占式多任务处理。 谢谢。


Thread.Suspend是邪恶的。它的邪恶程度大约是Thread.Abort。如果代码在任意、不可预测的位置暂停,几乎没有任何代码是安全的。它可能持有一个锁,导致其他线程也暂停。您很快就会在系统的其他部分遇到死锁或不可预测的停顿。

想象一下你不小心暂停了静态构造函数string。现在所有想要使用的代码string也被停止。Regex内部使用锁定的缓存。如果您在该锁被全部占用时暂停Regex相关代码可能会暂停。这只是两个令人震惊的例子。

可能是在内部深处挂起一些代码Console类正在产生意想不到的后果。

我不知道该向您推荐什么。这似乎是一项学术练习,所以幸运的是,这对您来说不是生产问题。用户态等待和取消在实践中必须配合。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 控制线程(恢复/挂起) 的相关文章

  • 按成员序列化

    我已经实现了template
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • asp.net core / kestrel中的线程管理

    我正在解决我们已迁移到 asp net core 2 0 的 asp net 应用程序的性能 可扩展性问题 我们的应用程序作为应用程序服务托管在 azure 上 并且在任何中等流量的情况下都很容易崩溃 让我困惑的一件事是如何处理多个并发请求
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • 链接器错误:已定义

    我尝试在 Microsoft Visual Studio 2012 中编译我的 Visual C 项目 使用 MFC 但出现以下错误 error LNK2005 void cdecl operator new unsigned int 2
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • 如何将带有 IP 地址的连接字符串放入 web.config 文件中?

    我们当前在 web config 文件中使用以下连接字符串 add name DBConnectionString connectionString Data Source ourServer Initial Catalog ourDB P
  • 静态变量的线程安全

    class ABC implements Runnable private static int a private static int b public void run 我有一个如上所述的 Java 类 我有这个类的多个线程 在里面r
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况

随机推荐