这真的是一个非法的跨线程调用吗? [英] Is this really an Illegal Cross Thread Call?
问题描述
我有一个Thread回调Form函数改变Form数据。
当然,调试器告诉我,跨线程操作无效:
控制''FormTest''从一个线程以外的线程访问
创建。
但我锁定之前我触摸共享数据,所以我真的需要担心这个,或者只是调试器过于简单?
具体来说,我有:
public delegate void TestEvent(ref string Payload);
public class FormTest:System.Windows.Forms.Form
{
...
无效运行
{
TestHarness test = new TestHarness();
test.Callback + = TestFunction; //回调的类型是
TestEvent
线程t =新线程(新的ThreadStart(test.Go));
t.IsBackground = true;
t.Start();
}
private void TestFunction(ref string Payload)
{
lock(this)WriteOut(ref Payload); // ???这不是锁定
防止线程同步问题???
}
private void WriteOut(ref string Payload)
{
this.Text =有效载荷;
}
I have a Thread making a callback to a Form function that alters Form data.
Of course, the debugger is telling me, "Cross-thread operation not valid:
Control ''FormTest'' accessed from a thread other than the thread it was
created on."
But I am locking before I touch the shared data, so do I actually need to
worry about this, or is it just the debugger being oversimplistic?
Specifically, I have:
public delegate void TestEvent(ref string Payload);
public class FormTest : System.Windows.Forms.Form
{
...
void Run
{
TestHarness test = new TestHarness();
test.Callback += TestFunction; // Callback is of type
TestEvent
Thread t = new Thread(new ThreadStart(test.Go));
t.IsBackground = true;
t.Start();
}
private void TestFunction(ref string Payload)
{
lock(this) WriteOut(ref Payload); // ??? Doesn''t this lock
prevent thread synchronization problems???
}
private void WriteOut(ref string Payload)
{
this.Text = Payload;
}
推荐答案
Dave,
Dave,
但我在触摸共享数据之前就锁定了,所以我实际上需要担心这个,或者只是调试器过于简单化了?
But I am locking before I touch the shared data, so do I actually need to
worry about this, or is it just the debugger being oversimplistic?
是的警告是对的。您应该只从它们创建的线程访问Winforms控件
。 Lock在这里没有帮助。
Mattias
-
Mattias Sj?gren [C#MVP] mattias @ mvps .org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
请回复到新闻组。
Yes the warning is right. You should only access Winforms controls
from the thread they were created on. Lock doesn''t help here.
Mattias
--
Mattias Sj?gren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
感谢您发帖。
如果您使用多线程来提高性能你的Windows窗体
应用程序,你必须小心以
线程安全的方式调用你的控件。
对Windows窗体控件的访问本质上不是线程安全的。如果你有两个或多个线程来操纵一个控件的状态,那么可能会使控件进入一个不一致的状态。其他与线程相关的错误也可能是
,包括竞争条件和死锁。确保以线程安全的方式访问您的控件非常重要
。
.NET Framework可帮助您检测何时访问您的控件以
a方式不是线程安全的。当您在
中运行应用程序时,调试器以及创建控件的线程以外的线程
尝试调用该控件,调试器会引发一个>
InvalidOperationException,消息,控制控件名称从其创建的线程以外的线程访问
。
要以线程安全的方式访问控件,您应该使用
控件的Invoke方法。以下是一个示例。
delegate void WriteOutDelegate(ref string Payload);
void test_Callback(ref string Payload)
{
object [] args = new object [1] {Payload};
this.Invoke(new WriteOutDelegate(WriteOut),args);
}
private void WriteOut(ref string Payload)
{
this.Text = Payload;
}
希望这会对你有所帮助。
如果您有任何其他问题,或需要其他任何事情,请不要
犹豫要告诉我。
此致,
Linda Liu
Microsoft在线社区支持
/>
============================================ ====== ==
在回复帖子时,请回复群组通过
您的新闻阅读器,以便其他人可以从您的问题中学习并从中获益。
============ ====================================== ==
Hi,
Thank you for posting.
If you use multithreading to improve the performance your Windows Forms
applications, you must be careful to make calls to your controls in a
thread-safe way.
Access to Windows Forms controls is not inherently thread safe. If you have
two or more threads manipulating the state of a control, it is possible to
force the control into an inconsistent state. Other thread-related bugs are
possible as well, including race conditions and deadlocks. It is important
to ensure that access to your controls is done in a thread-safe way.
The .NET Framework helps you detect when you are accessing your controls in
a manner that is not thread safe. When you are running your application in
the debugger, and a thread other than the one which created a control
attempts to call that control, the debugger raises an
InvalidOperationException with the message, "Control control name accessed
from a thread other than the thread it was created on."
To make the access to your controls in a thread-safe way, you should use
the Invoke method of the control. The following is a sample.
delegate void WriteOutDelegate(ref string Payload);
void test_Callback(ref string Payload)
{
object[] args = new object[1]{Payload};
this.Invoke(new WriteOutDelegate(WriteOut),args);
}
private void WriteOut(ref string Payload)
{
this.Text = Payload;
}
Hope this will help you.
If you have any other concerns, or need anything else, please don''t
hesitate to let me know.
Sincerely,
Linda Liu
Microsoft Online Community Support
================================================== ==
When responding to posts,please "Reply to Group" via
your newsreader so that others may learn and benefit
from your issue.
================================================== ==
Dave Booker写道:
Dave Booker wrote:
我有一个Thread回调Form函数改变Form数据。
当然,调试器告诉我, 跨线程操作无效:
控制''FormTest''从其创建的线程以外的线程访问。
但我锁定在我触摸共享数据之前,我是否真的需要担心这个问题,或者只是调试器过于简单?
I have a Thread making a callback to a Form function that alters Form data.
Of course, the debugger is telling me, "Cross-thread operation not valid:
Control ''FormTest'' accessed from a thread other than the thread it was
created on."
But I am locking before I touch the shared data, so do I actually need to
worry about this, or is it just the debugger being oversimplistic?
是的,你需要担心它。 UI组件具有线程亲和力 -
他们真的,除了他们自己的线程之外真的不应该被触及。
(除了调用CreateGraphics,InvokeRequired,BeginInvoke
和Invoke。)
另外一个注意事项 - 你似乎是通过
引用传递字符串引用而不使用by-ref语义。
有这个原因吗?您可能不知道参数传递的工作原理。请参阅
http://www.pobox.com/ ~sibet / csharp / parameters.html
Jon
Yes, you need to worry about it. UI components have thread affinity -
they really, really shouldn''t be touched except on their own thread.
(Aside from the calls to CreateGraphics, InvokeRequired, BeginInvoke
and Invoke.)
One further note - you appear to be passing string references by
reference without using the by-ref semantics. Is there a reason for
this? You may be unaware of how parameter passing works. See
http://www.pobox.com/~skeet/csharp/parameters.html
Jon
这篇关于这真的是一个非法的跨线程调用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!