有关线程的一个问题,求高手给看看,怎么实现这一效果

焖三爷 2013-07-22 03:35:50
private static TimeSpan sleepTime = new TimeSpan(0, 0, 6);//定义了一个休眠时间
现在有线程A,重复执行方法AMethod()然后-->sleep(sleepTime);
AMethod()
{
/***********省略***********/
sleepTime = new TimeSpan(x, y, z);//重新定义了休眠时间
}

现在我想做的是有个方法去通知A线程,如果A在休眠,让A唤醒立即去执行Amethod()方法。
唤醒A我使用的是A.Interrupt();但是这个方法之后,再去执行sleep()方法会报错,好像是执行过Interrupt();之后就不再允许sleep了。
还有一个疑问是如果线程A正在执行AMethod(),我希望在执行完AMethod()之后再去让线程从头开始跑。但是上面我的思路不对,可能会引发冲突。
写的比较乱,不知道你们看懂了没有 求高手帮看下
...全文
442 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
烈火蜓蜻 2013-07-22
  • 打赏
  • 举报
回复
引用 26 楼 liu610721 的回复:
[quote=引用 24 楼 Linux7985 的回复:] [quote=引用 23 楼 liu610721 的回复:] [quote=引用 22 楼 Linux7985 的回复:] [quote=引用 21 楼 liu610721 的回复:] [quote=引用 20 楼 Linux7985 的回复:] 看一下,你的Handler是怎么定义的? setSleepTime(1, 5760);这个到底是多少时间?
这是我随便写的一个值计算出来是 15s 但是线程是一直在跑的[/quote] 把你的代码贴出来吧,看看sleepTime在哪里定义的[/quote]

/// <summary>
        /// 设置休眠时间
        /// </summary>
        /// <param name="day">天数</param>
        /// <param name="count">次数</param>
        private static void setSleepTime(int day, int count)
        {
            int minCount = day*24*60;   //day天总共分钟数
            int perMin = minCount/count;    //时间间隔xx分钟

            int days = perMin / 1440;     //天数
            int hours = (perMin - days * 1440) / 60;     //小时数
            int mins = perMin - days*1440 - hours*60; //分钟数
            sleepTime = new TimeSpan(days, hours, mins, 0);
        }
[/quote] 一看就知道你的SleepTime等于0,他还能停下来吗? 你为什么要搞的这么复杂, new TimeSpan(0,0,15);不就完事了吗? 你自己断点看一下,是不是0,[/quote] 不好意思 设计的是精确到分钟 所以我的测试是错误的 是00 现在按你这个方法OK了 谢谢[/quote] 记得给分就成。哈哈。
焖三爷 2013-07-22
  • 打赏
  • 举报
回复
引用 24 楼 Linux7985 的回复:
[quote=引用 23 楼 liu610721 的回复:] [quote=引用 22 楼 Linux7985 的回复:] [quote=引用 21 楼 liu610721 的回复:] [quote=引用 20 楼 Linux7985 的回复:] 看一下,你的Handler是怎么定义的? setSleepTime(1, 5760);这个到底是多少时间?
这是我随便写的一个值计算出来是 15s 但是线程是一直在跑的[/quote] 把你的代码贴出来吧,看看sleepTime在哪里定义的[/quote]

/// <summary>
        /// 设置休眠时间
        /// </summary>
        /// <param name="day">天数</param>
        /// <param name="count">次数</param>
        private static void setSleepTime(int day, int count)
        {
            int minCount = day*24*60;   //day天总共分钟数
            int perMin = minCount/count;    //时间间隔xx分钟

            int days = perMin / 1440;     //天数
            int hours = (perMin - days * 1440) / 60;     //小时数
            int mins = perMin - days*1440 - hours*60; //分钟数
            sleepTime = new TimeSpan(days, hours, mins, 0);
        }
[/quote] 一看就知道你的SleepTime等于0,他还能停下来吗? 你为什么要搞的这么复杂, new TimeSpan(0,0,15);不就完事了吗? 你自己断点看一下,是不是0,[/quote] 明天把其他代码整理下 效果应该可以实现
焖三爷 2013-07-22
  • 打赏
  • 举报
回复
引用 24 楼 Linux7985 的回复:
[quote=引用 23 楼 liu610721 的回复:] [quote=引用 22 楼 Linux7985 的回复:] [quote=引用 21 楼 liu610721 的回复:] [quote=引用 20 楼 Linux7985 的回复:] 看一下,你的Handler是怎么定义的? setSleepTime(1, 5760);这个到底是多少时间?
这是我随便写的一个值计算出来是 15s 但是线程是一直在跑的[/quote] 把你的代码贴出来吧,看看sleepTime在哪里定义的[/quote]

/// <summary>
        /// 设置休眠时间
        /// </summary>
        /// <param name="day">天数</param>
        /// <param name="count">次数</param>
        private static void setSleepTime(int day, int count)
        {
            int minCount = day*24*60;   //day天总共分钟数
            int perMin = minCount/count;    //时间间隔xx分钟

            int days = perMin / 1440;     //天数
            int hours = (perMin - days * 1440) / 60;     //小时数
            int mins = perMin - days*1440 - hours*60; //分钟数
            sleepTime = new TimeSpan(days, hours, mins, 0);
        }
[/quote] 一看就知道你的SleepTime等于0,他还能停下来吗? 你为什么要搞的这么复杂, new TimeSpan(0,0,15);不就完事了吗? 你自己断点看一下,是不是0,[/quote] 不好意思 设计的是精确到分钟 所以我的测试是错误的 是00 现在按你这个方法OK了 谢谢
  • 打赏
  • 举报
回复
timer内部就是用的多线程,只不过将线程的调度“隐藏起来了”,让你只需要关心业务逻辑的实现
烈火蜓蜻 2013-07-22
  • 打赏
  • 举报
回复
引用 23 楼 liu610721 的回复:
[quote=引用 22 楼 Linux7985 的回复:] [quote=引用 21 楼 liu610721 的回复:] [quote=引用 20 楼 Linux7985 的回复:] 看一下,你的Handler是怎么定义的? setSleepTime(1, 5760);这个到底是多少时间?
这是我随便写的一个值计算出来是 15s 但是线程是一直在跑的[/quote] 把你的代码贴出来吧,看看sleepTime在哪里定义的[/quote]

/// <summary>
        /// 设置休眠时间
        /// </summary>
        /// <param name="day">天数</param>
        /// <param name="count">次数</param>
        private static void setSleepTime(int day, int count)
        {
            int minCount = day*24*60;   //day天总共分钟数
            int perMin = minCount/count;    //时间间隔xx分钟

            int days = perMin / 1440;     //天数
            int hours = (perMin - days * 1440) / 60;     //小时数
            int mins = perMin - days*1440 - hours*60; //分钟数
            sleepTime = new TimeSpan(days, hours, mins, 0);
        }
[/quote] 一看就知道你的SleepTime等于0,他还能停下来吗? 你为什么要搞的这么复杂, new TimeSpan(0,0,15);不就完事了吗? 你自己断点看一下,是不是0,
焖三爷 2013-07-22
  • 打赏
  • 举报
回复
引用 22 楼 Linux7985 的回复:
[quote=引用 21 楼 liu610721 的回复:] [quote=引用 20 楼 Linux7985 的回复:] 看一下,你的Handler是怎么定义的? setSleepTime(1, 5760);这个到底是多少时间?
这是我随便写的一个值计算出来是 15s 但是线程是一直在跑的[/quote] 把你的代码贴出来吧,看看sleepTime在哪里定义的[/quote]

/// <summary>
        /// 设置休眠时间
        /// </summary>
        /// <param name="day">天数</param>
        /// <param name="count">次数</param>
        private static void setSleepTime(int day, int count)
        {
            int minCount = day*24*60;   //day天总共分钟数
            int perMin = minCount/count;    //时间间隔xx分钟

            int days = perMin / 1440;     //天数
            int hours = (perMin - days * 1440) / 60;     //小时数
            int mins = perMin - days*1440 - hours*60; //分钟数
            sleepTime = new TimeSpan(days, hours, mins, 0);
        }
烈火蜓蜻 2013-07-22
  • 打赏
  • 举报
回复
引用 21 楼 liu610721 的回复:
[quote=引用 20 楼 Linux7985 的回复:] 看一下,你的Handler是怎么定义的? setSleepTime(1, 5760);这个到底是多少时间?
这是我随便写的一个值计算出来是 15s 但是线程是一直在跑的[/quote] 把你的代码贴出来吧,看看sleepTime在哪里定义的
焖三爷 2013-07-22
  • 打赏
  • 举报
回复
引用 20 楼 Linux7985 的回复:
看一下,你的Handler是怎么定义的? setSleepTime(1, 5760);这个到底是多少时间?
这是我随便写的一个值计算出来是 15s 但是线程是一直在跑的
烈火蜓蜻 2013-07-22
  • 打赏
  • 举报
回复
看一下,你的Handler是怎么定义的? setSleepTime(1, 5760);这个到底是多少时间?
焖三爷 2013-07-22
  • 打赏
  • 举报
回复
引用 17 楼 Linux7985 的回复:
你可以在AMethod方法之后加个EventWaitHandler类应用。

EventWaitHandle handler = new EventWaitHandle(false, EventResetMode.AutoReset);
线程的函数a
void a()
{
    ......其它代码
    AMethod();
    handler.WaitOne(休眠的时间);
}
这样的话,你想线程快速的醒来,只要Handler.Set()一下就Ok了,
while (true)
            {
                doSth();
                setSleepTime(1, 5760);
                handler.WaitOne(sleepTime, false);
            }
线程还是一直在跑的,没有休眠
烈火蜓蜻 2013-07-22
  • 打赏
  • 举报
回复
引用 17 楼 Linux7985 的回复:
你可以在AMethod方法之后加个EventWaitHandler类应用。

EventWaitHandle handler = new EventWaitHandle(false, EventResetMode.AutoReset);
线程的函数a
void a()
{
    ......其它代码
    AMethod();
    handler.WaitOne(休眠的时间);
}
这样的话,你想线程快速的醒来,只要Handler.Set()一下就Ok了,
handler.WaitOne(休眠的时间);在休眠时间到了,或者有人调用Handler.Set()方法都会醒来继续往下执行。
烈火蜓蜻 2013-07-22
  • 打赏
  • 举报
回复
你可以在AMethod方法之后加个EventWaitHandler类应用。

EventWaitHandle handler = new EventWaitHandle(false, EventResetMode.AutoReset);
线程的函数a
void a()
{
    ......其它代码
    AMethod();
    handler.WaitOne(休眠的时间);
}
这样的话,你想线程快速的醒来,只要Handler.Set()一下就Ok了,
焖三爷 2013-07-22
  • 打赏
  • 举报
回复
引用 12 楼 dongxinxi 的回复:
[quote=引用 6 楼 liu610721 的回复:] [quote=引用 1 楼 tianlehui 的回复:] 真心没看懂……
我现在遇到的问题是线程Interrupt()之后无法再sleep() 还有就是如果线程正在执行AMethod()的时候调用Interrupt()会不会出问题 [/quote] 用定时器就不需要再“Interrupt()之后无法再sleep()” 要实现通知,你定义一个事件event EventHandler Completed 在启动定时器之前,你注册一下完成后的事件处理
this.Completed += (obj, e) => AMethod();
var timer = System.Timers.Timer(6 * 1000);
timer.Elapsed += (obj, e) => 
{
    AMethod();
    //当执行完以后触发, 参数或者状态你可以放在e里面
    if(this.Completed != null) this.Completed(...);
};
timer.Start();
[/quote] 这个考虑下,如果线程不行的话 试下这个
焖三爷 2013-07-22
  • 打赏
  • 举报
回复
引用 13 楼 Linux7985 的回复:
Interrupt()这个方法MS不会唤醒线程吧,他会引发一个中断异常。
MSDN上关于Thread类的方法我看了 好像没有唤醒线程的方法
焖三爷 2013-07-22
  • 打赏
  • 举报
回复
引用 11 楼 Linux7985 的回复:
你可以考虑一下使用Timer
我还是先考虑先用线程能不能实现 然后再考虑timer
烈火蜓蜻 2013-07-22
  • 打赏
  • 举报
回复
Interrupt()这个方法MS不会唤醒线程吧,他会引发一个中断异常。
  • 打赏
  • 举报
回复
引用 6 楼 liu610721 的回复:
[quote=引用 1 楼 tianlehui 的回复:] 真心没看懂……
我现在遇到的问题是线程Interrupt()之后无法再sleep() 还有就是如果线程正在执行AMethod()的时候调用Interrupt()会不会出问题 [/quote] 用定时器就不需要再“Interrupt()之后无法再sleep()” 要实现通知,你定义一个事件event EventHandler Completed 在启动定时器之前,你注册一下完成后的事件处理
this.Completed += (obj, e) => AMethod();
var timer = System.Timers.Timer(6 * 1000);
timer.Elapsed += (obj, e) => 
{
    AMethod();
    //当执行完以后触发, 参数或者状态你可以放在e里面
    if(this.Completed != null) this.Completed(...);
};
timer.Start();
烈火蜓蜻 2013-07-22
  • 打赏
  • 举报
回复
你可以考虑一下使用Timer
焖三爷 2013-07-22
  • 打赏
  • 举报
回复
引用 9 楼 Linux7985 的回复:
我的意思,你不能这样的方式来实现。 你不要用唤醒的方式,让他自己醒Ok?
我之所以唤醒它是因为现在休眠时间变了,我需要让线程立即重新执行下。如果不采用这种唤醒方式,怎么实现呢
烈火蜓蜻 2013-07-22
  • 打赏
  • 举报
回复
我的意思,你不能这样的方式来实现。 你不要用唤醒的方式,让他自己醒Ok?
加载更多回复(8)

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧