我所拥有的与此类似:
//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的聊天应用程序在c Sharp中创建一个基本的长轮询Web服务器.我想让线程输入一个方法,该方法要等到发生以下两种情况之一,要么为客户端显示数据,要么发生轮询超时.但是,我不希望线程被阻塞,过去我有一段时间实现了每个客户端都有一个线程并且线程被阻塞并信任我的方法……这不是一个好主意.示例中的5秒是任意的,实际时间可能介于1至5分钟之间.最后,我可能要使用的结构是一种客户端管理线程.一个通过列表询问每个客户端是否有工作要做的线程.如果客户端已达到超时或队列中有数据等待,则将适当的方法分派到线程池中,并且“客户端管理”线程将继续到下一个客户端.
像这样…
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; }
}
}