c# - 如何在不完全阻塞线程的情况下将线程池中的线程暂停执行一定时间?

标签 c# .net multithreading asynchronous threadpool

我有类似的东西:

//method being called by thread pool thread
public string someFunction(){
    string someString = "string";

    //Stuff happens

    //Need to wait for 5 seconds without blocking thread

    return someString;
}

问题是我需要将该方法的结果返回给调用它的方法,但是,我不希望它立即返回并且我不想阻塞线程。有没有一种方法可以让线程在该行暂停一段指定的时间,然后将线程释放回线程池,然后在超时后,其中一个线程池线程从它停止的地方开始并完成函数和返回值?


所有... 在花了一些时间阅读您的回复后,我现在意识到,在我想要的环境中,做我想要实现的目标是不太可能的。

虽然有一点解释。我正在尝试为我正在构建的基于 Web 的聊天应用程序创建一个基本的长轮询 Web 服务器。我想让线程进入一个方法,它等待直到发生以下两种情况之一,要么数据显示给客户端,要么发生轮询超时。但是,我不希望线程阻塞,过去有一段时间我实现了一些东西,每个客户端都有一个线程并且线程阻塞了,相信我......这不是一个好主意。示例中的 5 秒是任意的,实际时间可能在 1 到 5 分钟之间。最后,我最终可能采用的结构是一种客户端管理线程。一个通过列表询问每个客户是否有工作要做的线程。如果客户端已超时或有数据在其队列中等待,则会将适当的方法分派(dispatch)到线程池中,并且客户端管理线程会继续处理下一个客户端。

类似这样的……

while(true){
    foreach(Client client in ClientList){
        //check if the client has something it needs done
        if(client.needsWork){
               //invoke the appropriate method asynchronously
               delegate = client.appropriateInvokable;
               delegate.beginInvoke();
        }
    }
}

非常感谢大家的帮助和耐心等待!

最佳答案

看完您的问题后,我发现这比在新线程上获取计时器回调要棘手一些。真正的问题是您的调用被构造为同步返回一个值,因此您无法避免阻塞调用线程。避免阻塞的正确方法是将您的调用更改为使用异步回调而不是直接返回值。如果您有权访问 TPL,执行此操作的一种好方法是返回一个 Task 对象,然后调用者可以立即等待或注册回调。


就是说,对于计时回调方面,我有一些实用程序代码可用于简化在这些一次性计时器场景中使用 System.Threading.Timer 的工作。我已将其缩减为指定的功能并将其放在下面:

public sealed class TimerService
{
    /// <summary>
    ///   This method registers a call back to be called after a specified period of time.
    /// </summary>
    /// <param name = "duration">The duration after which to call back</param>
    /// <param name = "callback">The method to call back</param>
    public void WhenElapsed(TimeSpan duration, Action callback)
    {
        if (callback == null) throw new ArgumentNullException("callback");

        //Set up state to allow cleanup after timer completes
        var timerState = new TimerState(callback);
        var timer = new Timer(OnTimerElapsed, timerState, Timeout.Infinite, Timeout.Infinite);
        timerState.Timer = timer;

        //Start the timer
        timer.Change((int)duration.TotalMilliseconds, Timeout.Infinite);
    }

    private void OnTimerElapsed(Object state)
    {
        var timerState = (TimerState)state;
        timerState.Timer.Dispose();
        timerState.Callback();
    }

    private sealed class TimerState
    {
        public TimerState(Action callback)
        {
            Callback = callback;
        }

        public Timer Timer { get; set; }

        public Action Callback { get; private set; }
    }
}

关于c# - 如何在不完全阻塞线程的情况下将线程池中的线程暂停执行一定时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8934750/

相关文章:

c# - 使用 .NET 中的 Interlocked 类实现按位运算

Python:为什么线程函数比非线程函数慢

c# - 将 Stream 对象转换为 json 对象,然后转换为用户定义的对象

c# - 使用@符号时如何在字符串中使用双引号?

c# - 新的 Outlook 邮件消息不加载

.net - 如何使用 .NET 2.0 将 PDF 文件作为二进制流传输到浏览器

c# - IDE0057 子串可以简化

c# - 如何正确暂停/停止线程?

c# - 文件分割器和连接器

c# - Asp.net MVC 样板依赖注入(inject)不起作用