多线程问题 [英] Multi Thread Issues

查看:85
本文介绍了多线程问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好!我在遇到线程异常时遇到了一些麻烦.我有一个程序可以通过命令行监听打开文件.如果打开了另一个实例,它将使用 [

 公共  WithEvents  PServer  As   wyDay.Controls.PipeServer

' 表单加载事件处理程序
PServer.Start(" )

'  PServer消息接收处理程序
私有  PServer_MessageReceived( ByVal  message()  As  字节)句柄 PServer.MessageReceived
     Dim  FinalMessage  As  字符串 = " 
    对于 每个事物 As  字节 传入消息
        FinalMessage = FinalMessage& Strings.Chr(事物)
    下一步
    '  Debug.Print(FinalMessage)
    Common.ProcessCommandLines({FinalMessage})
结束  



common.ProcessCommandLines是一个验证过程,正在继续进行到加载过程.我还无法弄清的另一件事是,在加载时,加载的表格会闪烁几次然后消失(问题可能是相关的).无论如何,加载过程会将表格添加到Array中.当我调用我的前移函数时会发生问题,该函数会遍历数组并告诉每种表单都移到最前面.除非我有一个加载的表格经过上述过程,否则它可以正常工作.

如果有人知道如何解决此问题,请告诉我.如果需要更多信息,也请告诉我.

谢谢!
Ethan

是的,某些.NET库方法拒绝从除构造对象的线程之外的其他线程中调用.
有关更多详细信息,您需要准确地发现此异常并提供此异常的转储(更好地具有完整的异常步骤和所有内部异常,以递归方式).至少,它需要最初引发异常的行.

假设您确定异常及其原因,我认为只有一些方法可以解决问题:

1)重构代码以在同一线程中构造和使用违规"对象;

2)开发一种用于线程间调用分配的机制.参见下文.

对于System.Windows.Forms和WPF UI线程已经存在这样的机制(请参见Dispatcher).我将不做进一步解释,因为您正在开发一些服务器(如果需要了解更多信息,请问我).要结束此子主题,很高兴知道可以通过Dispatcher进行调用,可以在任何地方正式进行,但是如果线程不是.NET UI,则结果是微不足道的(相当于常规调用).由于这与服务器开发无关,因此我稍后可以提供进一步的解释.

对于一般情况下的线程(例如您的服务器线程),调度机制仅特定于应该生成真实代码的线程.进行调用的线程可以是任何东西.因此,具有分派机制的线程应提供某些委托类型的委托队列,并在一个循环中从队列中检索数据.要在队列为空时使线程休眠,可以使用带有手动触发的System.Threading.EventHandle,但这会阻塞线程,因此无法并行执行其他活动(创建单独的线程).调用该动作的线程应该简单地提供委托的实例和实例(非常欢迎使用匿名方法)来调用一些将委托元素放入队列的方法.此调用是非阻塞的.

仅当您说服我这样做时,我才能提供其他帮助-这相对容易,但需要一些工作时间.最有可能的是,第一种方法(重新分解)是您服务器上唯一合理的方法.这根本不是真的,sendmessage确实如此-postmessage并非如此.

他继续指出,sendmessage/postmessage仅允许使用整数值,在某种程度上是正确的,但是该整数值可以是指向对象的指针,从而允许传递复杂类型.

第三,如果正确处理线程问题,则完全不需要IPC.对于.Net,除非您以非常特定的方式进行操作,否则无法从线程更新UI.您可能应该用谷歌搜索"vb.net从线程更新用户界面",并且应该可以回答所有问题.


Matchlighter,我记得您对重新分解的前景不太满意线程(以确保您在同一线程中创建和使用某些对象),并对线程间调用表示兴趣.

当其他问询者提出更多问题时,我需要建议非常相似的食谱,因此我在技巧/窍门"中以小文章的形式介绍了一些基本技术.这是我最近描述线程间调用的技巧(尤其是上次使用的示例):

用于线程通信和线程间调用的简单阻塞队列 [ ^ ].

好吧,很抱歉,这只是C#,而不是VB.NET.如果您有兴趣,则不必知道C#的详细信息.您可以创建一个C#库项目,在其中添加类(泛型),然后从VB.NET使用.如果您有问题,请发表问题(作为对我的回答的评论).

祝你好运,
—SA


Hello! I am having a little trouble with a threading Exception. I have a program that listens opens files through command line. If another instance is open, it will use this[^] method of Piping. However, I think that it may be causing the "Cannot be called through a thread that did not create it" exception.

Public WithEvents PServer As New wyDay.Controls.PipeServer

'Form Load Event Handler
PServer.Start("\\.\pipe\MainNotesPipe")

'PServer Message Received Handler
Private Sub PServer_MessageReceived(ByVal message() As Byte) Handles PServer.MessageReceived
    Dim FinalMessage As String = ""
    For Each thing As Byte In message
        FinalMessage = FinalMessage & Strings.Chr(thing)
    Next
    'Debug.Print(FinalMessage)
    Common.ProcessCommandLines({FinalMessage})
End Sub



common.ProcessCommandLines is a verification process that goes move on toward a Load process. Another thing that I haven''t been able to figure out is, when it loads, the loaded form flickers a couple of times and then disappears (the issues might be related). Anyhow, The load process adds the form to an Array. The problem occurs when I call my bring-to-front function which goes through the array and tells each form to come to the front. It works properly except when I have a loaded form that went through the above process.

If anyone knows how I can fix this, please let me know. Please let me know if anymore info is needed as well.

Thanks!
Ethan

解决方案

Yes, some .NET library methods refuse to be called from a thread other then the thread where the object was constructed.

For more detail, you need to spot this exception exactly and provide a dump of this exception (better with full exception step and all inner exceptions, recursively). At least, it needs the line where exception was originally thrown.

Assuming you''re sure about exception and its cause, I think there are only to methods to resolve the problem:

1) Re-factor the code to have the "offender" object constructed and used in the same thread;

2) Develop a mechanism for inter-thread dispatching of calls. See below.

Such mechanisms already exist for System.Windows.Forms and WPF UI threads (see Dispatcher). I''m not explaining this further, because you''re developing some Server (ask me if you need to know more). To close up this sub-topic, it''s good to know that invocation through Dispatcher can be formally done anywhere, but the result is trivial (equivalent to normal call) if the thread is not .NET UI. As this is irrelevant to server development, I can provide further explanation later.

For a general-case thread, such as your server''s thread, the dispatching mechanism is only specific to the thread that is supposed to make a real code. The thread doing invocation can be anything. So the thread with dispatching mechanism should provide a queue of delegates of some delegate types and retrieve data from the queue in a cycle. To cause the thread sleeping when the queue is empty System.Threading.EventHandle with manual triggering can be used, but that will block the thread, so other activities cannot be carried out in parallel (make a separate thread). The thread which invokes the action should simply provide and instance of the delegate (anonymous methods are highy welcome) to call some method which place a delegate element in the queue; this call is non-blocking.

I could provide additional assistance, only if you convince me to do so -- this is relatively easy but need a bit of working time. Most likely, first method (re-factorization) is the only reasonable for your server.


The wyday blog says that using sendmessage/getmessage blocks the apps while the message is being processed. That''s simply not true, sendmessage does - postmessage does not.

He goes on to state that sendmessage/postmessage only allows intger values, that''s true to some extent, but that integer value can be a pointer to an object, thus allowing the passing of complex types.

Third, IPC is completely unnecessary if you handle threading issues correctly. For .Net, you cannot update the UI from a thread unless you do it in a very specific way. You should probably google "vb.net update UI from thread", and that should answer all of your questions.


Matchlighter, I remembered you were not very happy with the prospect of re-factorization of threading (to make sure you create and use some object in the same thread) and expressed interest in inter-thread invocation.

As other Inquirers asked more question which required me to advise very similar recipes, I''m putting some basic techniques in the form of small articles in Tips/Trick. Here my recent tip which describes inter-thread invocation (especially last usage sample):

Simple Blocking Queue for Thread Communication and Inter-thread Invocation[^].

Well, I''m sorry this is just C# and not VB.NET. If you''re interested, you don''t have to know C# detail; you could just created a C# library project, add classes there (generic) and use from VB.NET. Please post a question (as a comment to my answer) if you have questions.

Good luck,
—SA


这篇关于多线程问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆