V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cshcool
V2EX  ›  编程

C# 如何在执行后台耗时操作时,保证界面上的数字时钟持续地走。

  •  
  •   cshcool · 2014-04-28 12:40:54 +08:00 · 7291 次点击
    这是一个创建于 3655 天前的主题,其中的信息可能已经有所发展或是发生改变。
    后台的耗时操作时调用厂家提供的DLL,耗时在15秒左右,在网上找了几种方法,backgroudworker、invoke、begininvoke等,都没有成功,在执行后台操作时,界面会卡住。
    12 条回复    2014-04-29 23:19:17 +08:00
    cxe2v
        1
    cxe2v  
       2014-04-28 13:02:36 +08:00   ❤️ 1
    新开一个线程去执行耗时的操作
    rebornix
        2
    rebornix  
       2014-04-28 13:05:54 +08:00   ❤️ 1
    比如你可以使用Task.Factory.StartNew()

    当然为了perserve synchronization context,你可以用async/await.
    thinkif
        3
    thinkif  
       2014-04-28 13:59:41 +08:00
    其实你找的方法是对的。。。
    dong3580
        4
    dong3580  
       2014-04-28 14:10:04 +08:00
    界面会卡住是因为你压根都没真正用到多线程,你只是用了多线程的那几个关键字.
    开个线程,单线程肯定是不行的.你可以尝试使用:
    Thread newThread=new Thread(function());
    newThread.Isbackground=true;
    newThread.Start();
    jasontse
        5
    jasontse  
       2014-04-28 14:10:48 +08:00 via iPad   ❤️ 1
    using System.Threading;

    Thread thread = new Thread(new ThreadStart(ThreadFunction));
    thread.Start();

    public void ThreadFunction()
    {
    // 耗时操作
    }
    tonghuashuai
        6
    tonghuashuai  
       2014-04-28 14:32:20 +08:00   ❤️ 1
    多线程
    cshcool
        7
    cshcool  
    OP
       2014-04-28 16:50:53 +08:00
    @dong3580 我用你的方法试了,耗时操作如果用 thread.sleep() 来模拟,程序运行正常。
    若将正式的耗时操作(从dll引入的函数)写入,新开的线程一旦执行到调用耗时操作的函数时,界面还是会先卡住10秒,随后的10秒虽然“耗时操作”仍未执行完,但界面上的时钟可以正常走,这问题出在哪?
    min
        8
    min  
       2014-04-28 17:00:31 +08:00
    解释一下那个dll做了些什么
    dong3580
        9
    dong3580  
       2014-04-28 17:05:02 +08:00
    @cshcool
    不能使用sleep,sleep的意思在这里是阻塞进程,与多线程没有毛线的关系.
    thread.sleep() ,例如thread.sleep(2000) 就是将该进程阻塞2s,
    新开线程:
    Thread t1=new Thread(这里面写上需要执行的方法);
    t1.Isbackground=true;//允许执行完方法之后自动回收内存
    t1.Start();//开始执行
    如果必要,可否给出你的程序精简代码,
    cshcool
        10
    cshcool  
    OP
       2014-04-28 17:25:38 +08:00
    @dong3580 谢谢!
    private void DoWork()
    {
    ....
    调用dll中的函数,耗时20秒左右(实际完成的是数据发送任务,发送成功的话就很快,失败就要等 待20秒左右才返回失败信息)
    ....

    }

    private void button1_Click(object sender, EventArgs e)
    {
    Thread Th = new Thread(new ThreadStart(StartMethod));
    Th.IsBackground = true;
    Th.Start();

    this.timer1.Enabled = true;

    }

    private void timer1_Tick(object sender, EventArgs e)
    {
    Thread.Sleep(1000);
    this.label1.Text = GetTime(); //显示当前时间
    }
    dong3580
        11
    dong3580  
       2014-04-28 17:34:49 +08:00
    1.这个Thread.Sleep(1000);可以用timer设置时间间隔代替,你在这里写会造成界面卡顿1s;
    2.多线程的话:这个this.label1.Text = GetTime(); 会造成界面卡顿,建议新开线程执行,不然你的多线程有什么用呢?并不是新建了一个线程就是多线程.
    3.如果更改之后依然卡顿,最大的原因就是DoWork()方法的问题,如果这个方法里面都是用单线程完成一堆操作,你界面方法里面再怎么优化都没用.
    20s,我的神,这dll能用么.
    cshcool
        12
    cshcool  
    OP
       2014-04-29 23:19:17 +08:00
    @dong3580 是啊,小厂家做的,不是专业开发软件的,连他们提供的示例软件都卡得没法用。
    我改了下程序,现在的情况是,第一次执行耗时程序会卡住,往后再执行都不会出现任何卡顿。
    在你帮助下已经有很大进展,非常感谢!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   876 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 21:02 · PVG 05:02 · LAX 14:02 · JFK 17:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.