日期:2014-05-18  浏览次数:21242 次

c# 子线程如何通知主线程,使主线程做出响应?
我要实现的功能如下:

程序中有2个线程,主线程和子线程,
主线程中有一个变量:X
主线程运行中激活子线程,子线程会做出计算改变 X 的值,
主线程继续做其它的事,直到 X 的值发生改变时,才会响应,并在textbox中输出 X 的值(这一过程中主线程并不知道何时X的值才会变,它不能循环等待,必须去做别的事,比如接收用户点击等等)。

这个功能看起来简单,但是我始终找不到方法,我对委托和事件理解的还不透,不知道能不能用事件解决?
期待各位高手解答



------解决方案--------------------
你这也是委托的问题,参考一下:
C# code

private void button1_Click(object sender, EventArgs e)
{
    Thread th = new Thread(aa);
    th.Start();
}

delegate void somedle();
private void aa()
{
    if (this.InvokeRequired)
    {
        somedle sd = new somedle(aa);
        this.Invoke(sd);
        return;
    }
    ShowChar('A');
}
public void ShowChar(char ch)
{
    lock (this)
    {
        textBox1.Text += ch;
    }
}

------解决方案--------------------
static void Main(string[] args)
{
ManualResetEvent myResetEvent = new ManualResetEvent(false);

int X = 0;

Thread childThread = new Thread(delegate()
{
//Console.WriteLine(Thread.CurrentThread.Name + " " + Thread.CurrentThread.ManagedThreadId);

Console.WriteLine("Set X Value");
X = 10;
Console.WriteLine("Set X Value end");

Console.WriteLine("Notice main thread");
myResetEvent.Set();
});

childThread.Start();

while (true)
{
if (myResetEvent.WaitOne())
{
Console.WriteLine("After child thread set X, X is " + X);
myResetEvent.Reset();
}
}

Console.ReadKey();
}

这里主要是ManualResetEvent的应用,和前面的兄弟提到的autoresetevent 是差不多的,区别自己看下msdn
------解决方案--------------------
探讨
引用:
将X封装成属性

在Set里写入需要触发的代码不就可以了?不一定要主线程去做,子线程当然也可以做的。


推荐这种做法,封装一个事件,形如OnXChanged,主线程中注册此事件,事件触发时就会转到对应代码执行去了。

当然,此时仍是在子线程中执行的。

如一定要主线程去做事,考虑使用信号量、WatiHandle等线程同步机制吧

------解决方案--------------------
C# code

public delegate void SetIntValue(int value);

public void setX(int value)
{
    if (InvokeRequired)
    {
        // 在子线程中调用此方法时,通过Invoke转成主线程执行
        Invoke(new SetIntValue(value));
        return;
    }

    // 设置X值并显示
    X = value;
    textbox.Text = X.toString();
}