C#线程方面的一个问题,谢谢!
privatevoidRun(){while(true){/*1*/this.BeginInvoke(newMethodInvoker(()=>{textBox1.Tex...
private void Run()
{
while (true)
{
/*1*/this.BeginInvoke(new MethodInvoker(() =>
{
textBox1.Text = textBox1.Text.Substring(1) + textBox1.Text.Substring(0, 1);
}));
/*2*/this.textBox1.Text = this.textBox1.Text.Substring(1) + this.textBox1.Text.Substring(0, 1);
Thread.Sleep(100);
}
}
}
如图代码,是实现TextBox滚动字幕的代码。单击一个按钮后,启动一个线程,该线程将执行这个方法。代码中有/*1*/和/*2*/两种不同的实现方式(当然真正运行的时候注释掉一种)。
第二种比较简单,一目了然。但是第一种,不太理解。据说这么使用是因为TextBox是主线程创建的,子线程最好不要使用主线程创建的东西(即操纵TextBox的Text属性),所以需要使用这么一种方式加强安全性。
问题:第一种方式真的有必要吗?具体如何理解(即BeginInvoke和MethodInvoker的比较好理解的意思,不要微软的那个解释)?谢谢 展开
{
while (true)
{
/*1*/this.BeginInvoke(new MethodInvoker(() =>
{
textBox1.Text = textBox1.Text.Substring(1) + textBox1.Text.Substring(0, 1);
}));
/*2*/this.textBox1.Text = this.textBox1.Text.Substring(1) + this.textBox1.Text.Substring(0, 1);
Thread.Sleep(100);
}
}
}
如图代码,是实现TextBox滚动字幕的代码。单击一个按钮后,启动一个线程,该线程将执行这个方法。代码中有/*1*/和/*2*/两种不同的实现方式(当然真正运行的时候注释掉一种)。
第二种比较简单,一目了然。但是第一种,不太理解。据说这么使用是因为TextBox是主线程创建的,子线程最好不要使用主线程创建的东西(即操纵TextBox的Text属性),所以需要使用这么一种方式加强安全性。
问题:第一种方式真的有必要吗?具体如何理解(即BeginInvoke和MethodInvoker的比较好理解的意思,不要微软的那个解释)?谢谢 展开
4个回答
展开全部
BeginInvoke和EndInvoke
我们已经知道,如何在不阻塞调用线程的情况下执行一个异步调用,但我们无法得知异步调用的执行结果,及它何时执行完毕。为了解决以上问题,我们可以使用EndInvoke。EndInvoke在异步方法执行完成前,都会造成线程的阻塞。因此,在调用BeginInvoke之后调用EndInvoke,效果几乎完全等同于以阻塞模式执行你的函数(EndInvoke会使调用线程挂起,一直到异步函数执行完毕)。但是,.NET是如何将BeginInvoke和EndInvoke进行绑定呢?答案就是IAsyncResult。每次我们使用BeginInvoke,返回值都是IAsyncResult类型,它是.NET追踪异步调用的关键值。每次异步调用之后的结果如何?如果要了解具体执行结果,IAsyncResult便可视为一个标签。通过这个标签,你可以了解异步调用何时执行完毕,更重要的是,它可以保存异步调用的参数传值,解决异步函数上下文问题。
http://www.2cto.com/kf/201110/109351.html
我们已经知道,如何在不阻塞调用线程的情况下执行一个异步调用,但我们无法得知异步调用的执行结果,及它何时执行完毕。为了解决以上问题,我们可以使用EndInvoke。EndInvoke在异步方法执行完成前,都会造成线程的阻塞。因此,在调用BeginInvoke之后调用EndInvoke,效果几乎完全等同于以阻塞模式执行你的函数(EndInvoke会使调用线程挂起,一直到异步函数执行完毕)。但是,.NET是如何将BeginInvoke和EndInvoke进行绑定呢?答案就是IAsyncResult。每次我们使用BeginInvoke,返回值都是IAsyncResult类型,它是.NET追踪异步调用的关键值。每次异步调用之后的结果如何?如果要了解具体执行结果,IAsyncResult便可视为一个标签。通过这个标签,你可以了解异步调用何时执行完毕,更重要的是,它可以保存异步调用的参数传值,解决异步函数上下文问题。
http://www.2cto.com/kf/201110/109351.html
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
用什么BeginInvoke啊,BeginInvoke应该和EndInvoke成对出现,你这里直接用Invoke就行了,在子线程中可以访问主线程创建控件的属性,但是不能对其进行操作,MethodInvoker
是一个委托(用来书写内联方法的),里面的委托你也可以这么写,
Invoke(MethodInvoker)delegate
{
//
});
是一个委托(用来书写内联方法的),里面的委托你也可以这么写,
Invoke(MethodInvoker)delegate
{
//
});
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
不是最好不要,而是必须要用,你用第二段代码会直接报错。至于具体的解释会牵引到线程和委托方面的内容,建议你先百度一下C# 跨线程 访问控件
追问
谢谢指导。
不知道为么,仅仅使用第二段的时候可以正常运行呢。老师上课讲的时候也是说必须要用第一种,可是在家试了试第二种似乎也可以呢。
麻烦指点,谢谢!
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
在没有理解之前学会模仿就行了,用多了你才会理解为什么这么做。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询