如何暂停线程

Semiman 2016-01-21 08:31:55
做一个类似腾讯云的上传客户端,多文件上传,一个文件是一个线程,每个文件都呈现进度条,现在我想暂停其中的某一个,然后可以继续开始,怎么处理?查了很多资料,试了很多次,弄了很久都没有成功,思路到底是怎么样的?请教各位大侠。
我目前的思路是添加一个文件上传就启动一个改变进度条的线程,在改变进度条的线程中又启动一个上传文件的线程,我点击暂停按钮通过信号来控制进度条暂停、重新上传,但上传的线程无法暂停。
@大侠sp1234,请教!
@bdmh 请教!
...全文
545 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
MR_HJ 2017-03-08
  • 打赏
  • 举报
回复
楼主解决没,我也有相同的问题
橘子皮... 2016-01-28
  • 打赏
  • 举报
回复
其实写1个大循环,有个好处就是做小软件比较快,代码看的简单,搞事件的话,要写很多东东
Semiman 2016-01-23
  • 打赏
  • 举报
回复
引用 8 楼 sp1234 的回复:
设计一个高性能高并发的软件,首先一点,就是要摒弃滥用什么”循环、线程“的思维习惯。 这里的文件是一块一块数据发送的,中间还需要让宿主程序的监听插件可以获得通知,那么自然就是要围绕着“发送一小块数据”这个行为来设计程序。 设计一个程序,不是动不动就弄一个“大大的死循环”、然后再去想循环内部怎么写。这种思维方式就会产生非常差的(但是因为循环结构很“大”很“长”所以可以在客套上哄骗不懂编程的学生)程序。 实际上,好的高性能高并发的程序流程,从细节入手,然后这些细节以事件驱动、异步回调的方式来形成一个数据流。并不是弄一大堆循环控制流。
我倒是没有用循环,只是上传文件的接口就一个方法,我也不能进行修改。
Semiman 2016-01-23
  • 打赏
  • 举报
回复
引用 8 楼 sp1234 的回复:
设计一个高性能高并发的软件,首先一点,就是要摒弃滥用什么”循环、线程“的思维习惯。 这里的文件是一块一块数据发送的,中间还需要让宿主程序的监听插件可以获得通知,那么自然就是要围绕着“发送一小块数据”这个行为来设计程序。 设计一个程序,不是动不动就弄一个“大大的死循环”、然后再去想循环内部怎么写。这种思维方式就会产生非常差的(但是因为循环结构很“大”很“长”所以可以在客套上哄骗不懂编程的学生)程序。 实际上,好的高性能高并发的程序流程,从细节入手,然后这些细节以事件驱动、异步回调的方式来形成一个数据流。并不是弄一大堆循环控制流。
大侠,我先消化一下你说的思路。谢谢
Semiman 2016-01-23
  • 打赏
  • 举报
回复
引用 9 楼 shingoscar 的回复:
[quote=引用 5 楼 Semiman 的回复:] 说错了,是在while初始状态不是暂停的时候线程就已经开始执行方法了。你的这个状态值肯定是要等执行方法执行了以后再设定状态值,而线程早已执行后续方法。
如果你所谓的后续方法是一次性把数据上传完毕,那这个判断确实没用,或者说这个while是多余的 然而实际的上传过程,每次只上传一部分字节,这是一个非常短暂的过程,当这一轮数据发送完毕,你又会回到while的判断,这样就能达到暂停的目的 所谓的线程暂停没有你想的那么完美,当按下某个按钮线程就立即停止这样的想法是不存在的[/quote] 你说的有道理。
五更琉璃 2016-01-22
  • 打赏
  • 举报
回复
你可以挂起线程,但是需要另一个线程在激活这个线程。
Poopaye 2016-01-21
  • 打赏
  • 举报
回复
引用 5 楼 Semiman 的回复:
说错了,是在while初始状态不是暂停的时候线程就已经开始执行方法了。你的这个状态值肯定是要等执行方法执行了以后再设定状态值,而线程早已执行后续方法。
如果你所谓的后续方法是一次性把数据上传完毕,那这个判断确实没用,或者说这个while是多余的 然而实际的上传过程,每次只上传一部分字节,这是一个非常短暂的过程,当这一轮数据发送完毕,你又会回到while的判断,这样就能达到暂停的目的 所谓的线程暂停没有你想的那么完美,当按下某个按钮线程就立即停止这样的想法是不存在的
  • 打赏
  • 举报
回复
设计一个高性能高并发的软件,首先一点,就是要摒弃滥用什么”循环、线程“的思维习惯。 这里的文件是一块一块数据发送的,中间还需要让宿主程序的监听插件可以获得通知,那么自然就是要围绕着“发送一小块数据”这个行为来设计程序。 设计一个程序,不是动不动就弄一个“大大的死循环”、然后再去想循环内部怎么写。这种思维方式就会产生非常差的(但是因为循环结构很“大”很“长”所以可以在客套上哄骗不懂编程的学生)程序。 实际上,好的高性能高并发的程序流程,从细节入手,然后这些细节以事件驱动、异步回调的方式来形成一个数据流。并不是弄一大堆循环控制流。
  • 打赏
  • 举报
回复
你可以看到,方法 Send 可以从“当前”发送中断的Position偏移处开始发送。每次发送一块数据,然后抛出事件通知自己的宿主(宿主可以通过Length、SendPositon来了解进度)。每一次Send成功之后,会自动启动下一个Send操作。可以通过 PauseFlag 来停止下一个数据块Send。过程中并不怎么占用所谓的”线程“,宿主程序可能写
ThreadPool.QueueUserWorkItem(h => tsk.Send());
来开始Send过程,瞬间之后,线程就释放给系统线程池了(而不是一直卡在那里),直到 BeginWrite 方法所注册的(匿名委托)回调方法被系统I/O线程执行的时候,才会再去瞬间又使用线程池中的线程。 由于使用了异步Write,所以并不死等。就算你并发发送100个大文件,那么也不会占用100个线程,或许有5个也就够了,因为大多数时间都是在等待异步回调,而不是让一堆线程卡在那里。
  • 打赏
  • 举报
回复
不要纠结什么“暂停线程”概念。大多数编程技术都是以业务流程控制为核心,而纠结技术术语不但不能解决问题且反而成事不足败事有余。 如果你发送单个文件是顺序的(多个文件并发发送),并且每当发送一个数据块之后就要通知一下宿主来关注进度,那么可以这样来设计其基本的数据结构和流程:
public class SendTask
{
    public Stream InputStream;
    public NetworkStream OutputStream;
    public int Length;
    public int SendPosition { private set; get; }
    public bool PauseFlag;

    private byte[] buffer = new byte[4000000];

    public void Send()
    {
        if (SendPosition < Length)
        {
            if (InputStream.Position != SendPosition)
                InputStream.Position = SendPosition;
            var len = InputStream.Read(buffer, 0, buffer.Length);
            if (len > 0)
            {
                OutputStream.BeginWrite(buffer, 0, len, x =>
                    {
                        OutputStream.EndWrite(x);
                        SendPosition += len;
                        if (SendPart != null)
                            SendPart();
                        if (!PauseFlag)
                            Send();
                    }, null);
            }
        }
    }

    public event Action SendPart;
}
Semiman 2016-01-21
  • 打赏
  • 举报
回复
引用 4 楼 Semiman 的回复:
[quote=引用 3 楼 shingoscar 的回复:] 你绝对没有“查了很多资料,试了很多次,弄了很久都没有成功” 这种问最简单像这样就能实现了
while(isStop)
{
    //做你想做的事情
}
......你这样的判断,在暂停任务之前就在while循环后面开始执行线程了。[/quote] 说错了,是在while初始状态不是暂停的时候线程就已经开始执行方法了。你的这个状态值肯定是要等执行方法执行了以后再设定状态值,而线程早已执行后续方法。
Semiman 2016-01-21
  • 打赏
  • 举报
回复
引用 3 楼 shingoscar 的回复:
你绝对没有“查了很多资料,试了很多次,弄了很久都没有成功” 这种问最简单像这样就能实现了
while(isStop)
{
    //做你想做的事情
}
......你这样的判断,在暂停任务之前就在while循环后面开始执行线程了。
Poopaye 2016-01-21
  • 打赏
  • 举报
回复
你绝对没有“查了很多资料,试了很多次,弄了很久都没有成功” 这种问最简单像这样就能实现了
while(isStop)
{
    //做你想做的事情
}
摇撼大地 2016-01-21
  • 打赏
  • 举报
回复
用TASK。子任务。和统一取消模型。 用Task.Factory创建一组子任务。不过看你好像不是统一取消。可以每个任务传入一个Token。一个任务一个TOken。然后执行函数里面判断Token是否被取消。
Semiman 2016-01-21
  • 打赏
  • 举报
回复
补充一点,上传列表是用listview控件。

110,571

社区成员

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

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

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