当前位置:编程学习 > C#/ASP.NET >>

C# 关于多线程暂停

这几天一直被一个问题给困扰..求大牛详细解答,小弟感激不尽.

主要的问题是 如何让一个线程暂停得到一个值后然后继续该线程

比如说程序运行到dataGridView的某个单元格得到焦点的时候线程挂起 不执行这个线程下面的语句
让用户输入值  失去焦点的时候取到dataGridView里面的值后然后恢复该线程 继续执行 下面的语句
因为dataGridView这个单元格里面的值接下来会用到

我尝试过好多方法 都不能达到那个效果

阻塞之后程序会崩溃 如果用挂起之后不用阻塞他会继续执行剩下的语句 导致我还没有取到值。。


求大牛们 解决下  感激不尽!!! --------------------编程问答-------------------- 你用一个全局变量,传递到线程里面,然后通过控制全局变量,来达到控制线程的目的,不就可以了吗 --------------------编程问答-------------------- 用互斥对象Mutex。在要等的地方wait,线程就被阻塞了。在值输入完后release,线程就继续往下走了。
这其实是线程的同步,除了Mutex之外,还可以用信号量、倒数计数等。 --------------------编程问答--------------------
引用 1 楼 xiaozhu39505 的回复:
你用一个全局变量,传递到线程里面,然后通过控制全局变量,来达到控制线程的目的,不就可以了吗


比如这样


Thread T = new Thread(f);
T.Start()
T.Suspend() //程序执行到这里 挂起线程

//失去焦点的时候恢复线程
T.Resume()      //怎么样才能让线程恢复过后再执行下面这句输入语句 如果没恢复则不执行

MessageBox.Show("子线程完成的工作");
void f()
{
      MessageBox.Show("子线程完成的工作");
}
--------------------编程问答--------------------
引用 2 楼 xxdddail 的回复:
用互斥对象Mutex。在要等的地方wait,线程就被阻塞了。在值输入完后release,线程就继续往下走了。
这其实是线程的同步,除了Mutex之外,还可以用信号量、倒数计数等。


能不能给个例子 讲解下,线程同步方面还没学。 --------------------编程问答--------------------
引用
能不能给个例子 讲解下,线程同步方面还没学。
就是建立一个互斥量,每次使用都判断是否可用,不可用就等,等你另一个线程把他释放了程序就继续了,  多线程的同步,,,概念不懂不用管,看下书,拿上来用就行,看到程序的效果一下子就懂了 --------------------编程问答-------------------- //声明定义:用这个比较好,
 AutoResetEvent detailCollectedEvent = new AutoResetEvent(false); 

------------------

//在想停的地方加上这句
detailCollectedEvent.WaitOne();


---------------------
//输入完值后可以使用这句:继续执行
 detailCollectedEvent.Set(); --------------------编程问答--------------------
引用 楼主 u013028695 的回复:
这比如说程序运行到dataGridView的某个单元格得到焦点的时候线程挂起 不执行这个线程下面的语句
让用户输入值  失去焦点的时候取到dataGridView里面的值后然后恢复该线程 继续执行 下面的语句
因为dataGridView这个单元格里面的值接下来会用到


多线程编程通常不需要阻塞。只有用线程的语法去模拟顺序执行的人,才会动不动就阻塞。

如果一个程序的连续操作它“断开”,那么就应该断开。例如一个线程可能去设置监听环境对象(为这个对象设置各种初始值),然后向dataGridView的单元格改变事件注册为这个监听对象的某个方法,然后这个线程就结束了!

等dataGridView的单元格修改了,这个方法可以被触发执行。如过你愿意,这个方法里边可以再启动另外一个线程来进行所谓“继续执行下面的语句”(因为之前的那个线程的运行结果状态已经被记录到监听对象中了,因此这你可以继续执行处理)。

这里可以看出,根本不存在什么阻塞!根本没有什么线程在哪里“没事阻塞”着,而都是100%地干正经事的线程执行。

如果你阻塞了,那么你可以想象出,你得能搞多少线程才够? --------------------编程问答-------------------- 这里有一个典型的错误概念,非常明显,就是有人说“要等待用户操作、要等待外设”于是要阻塞。

可以很明显地知道,这些人不懂事件编程,因此也就不会设计这种“两阶段”的线程程序。 --------------------编程问答-------------------- 懒得写麻烦的demo了,给你写一个console的例子:

这里你可以看到,开始一个线程操作跟随后在另一个线程中“继续处理”,是如何配合的。
using System;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var t = new TestProgram();
            while (true)
            {
                var k = Console.ReadKey();
                if (k.KeyChar == 'A' || k.KeyChar == 'a')
                    t.CreateTask("tsk_" + (++n));
                else if (k.KeyChar == 'B' || k.KeyChar == 'b')
                    t.Continue();
            }
        }

        static int n;
    }

    public class TestProgram
    {
        public event EventHandler Fire;

        public void CreateTask(string ttl)
        {
            ThreadPool.QueueUserWorkItem(h =>
            {
                Console.WriteLine("\r\n先执行前半部分,在一个线程中注册任务“{0}”,并且等待按下键盘b键........", ttl);
                var t = new MyTask
                {
                    title = ttl,
                    theTime = DateTime.Now
                };
                Fire += t.继续;
            });
        }

        public void Continue()
        {
            if (Fire != null)
                Fire(this, null);
        }
    }

    public class MyTask
    {
        public string title;

        public DateTime theTime;

        public void 继续(object sender, EventArgs e)
        {
            var tp = (TestProgram)sender;
            tp.Fire -= 继续;
            ThreadPool.QueueUserWorkItem(h =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("\r\n1秒过后,在另一个线程中完成了任务“{0}”(是{1}开始的任务)。", title, theTime);
            });
        }
    }
}
--------------------编程问答-------------------- 除
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,