将参数传递给线程化的LongRunningProcess [英] Passing arguments to a threaded LongRunningProcess

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

问题描述

johnsontroye'关于UI响应的文章让我大部分时间都遇到了在单独的线程上运行long方法的问题,但是我的应用程序有几个输入和返回的数据不适合这个例子。



似乎输入数据是正确的,但 API 调用无法正常运行。



我使用的是标准的Windows窗体而不是WPF,我将示例应用到我的应用程序并使用模拟的LongRunningMethod运行,但我无法将参数传递正确(?)我的LongRunningMethod(API调用):



johnsontroye''s article on UI Responsiveness got me most of the way through the problem of running a long method on a separate thread, but my application has several inputs and returned data that does not fit the example.

It seems as though the input data is correct, but the API call does not run correctly.

I am using a standard windows form instead of WPF, and I adapted the example to my application and got it running with the simulated LongRunningMethod, but I cannot get the argument passing correct (?) for my LongRunningMethod (API Call):

Private Function SomeLongRunningMethod((ByRef abData1() As Byte, _
                                       ByRef abData2() As Byte, _
                                       ByVal n As Integer, _
                                       ByRef abData3() As Byte) As String
     Dim someString as string = "1"
 
     abData1 = Method(abData1, abData2, n, abData3) ''API call
     
     Return SomeString
End Function





abData1()是一个大字节数组,与Method返回相同。



我很感激我能得到的任何帮助,因为我在很多例子中苦苦挣扎。



[已编辑]代码在预标签中被阻止[ / edited]



abData1() is a large byte array, and is the same as the Method return.

I would appreciate any help I can get with this, as I have struggled through many examples.

Code is blocked in "pre" tags[/Edited]

推荐答案

由于某种原因,建议的方法是使用 System.Threading.ParameterizedThreadStart



我从来没有这样做过!您必须传递 System.Object 参数,因此运行时间将是所有参数的某个容器( struct ,例如);并且在线程代码中你需要将 System.Object 强制转换回你的结构,这是不安全的。



我从来不明白为什么要这么丑陋的事情。有一个更好的方法。您只需传递我参考。我将整个线程包装在某个类中并创建一个方法,线程应该在我调用 Body 时启动。我做了它和实例(非静态)方法,没有参数(重要!)。使用常规构造函数 System.Threading.Thread(ThreadStart)允许传递 Body



由于 Body 是一个实例方法,所以包装类的所有成员都通过不可见参数 Me 包装类的类型;并且此参数无形地传递给 Body 。没有什么不寻常的 - 这就是所有实例方法的工作方式。但结果是,包装器 Body 的方法在一个线程中启动,并且该方法的成员类实例的所有成员都可见。因此,首先实例化包装类。您的问题中提到的所有参数都应该是包装器的成员。您需要在 Thread.Start 之前初始化它们。例如,你可以在包装器的构造函数中传递所有这些值。



我有一个完整的代码示例,但它在C#中:

如何将ref参数传递给线程 [ ^ ]。



尽管如此,使用我的解释很容易理解它是如何工作的。



祝你好运,

-SA
By some reason, the suggested method is using System.Threading.ParameterizedThreadStart.

I never do this! You have to pass a System.Object argument, so run-time time would be of some container for all your parameters (struct, for example); and in the thread code you need to cast System.Object back to your structure, which is unsafe.

I never understood why doing such ugly things. There is a much better way. All you need is to pass "Me" reference. I wrap whole thread in some class and create a method the thread should be started with I call Body. I make it and instance (non-static) method, without parameters (important!). Using a regular constructor System.Threading.Thread(ThreadStart) allows to pass Body.

As Body is an instance method, all members of the wrapper class are passed through the invisible parameter "Me" of the type of the wrapper class; and this parameter is passed invisibly to Body. There is nothing unusual about it — this is how all instance methods work. But as a result, the method of the wrapper Body is started in a thread and all members of the instance of the member class are visible inside the method. So, you instantiate the wrapper class first. All parameters mentioned in your Question should be members of the wrapper. You need to initialize them before Thread.Start. For example, you can pass all those values in the wrapper''s constructor.

I have a complete code sample, but it is in C#:
How to pass ref parameter to the thread[^].

Nevertheless it''s quite easy to understand how it work using my explanation.

Good luck,
—SA


我实施了SAKryukov建议的解决方案简化了变量的传递,API调用立即终止。我通过获取三个字节数组的散列并返回结果以与发送的变量进行比较来测试传递给线程的变量。此测试验证数据是否正确传递给线程,并且可以返回该数据。 API方法在主线程上正确运行。





I implemented the solution suggested by SAKryukov and while it simplifies the passing of variables, the API call terminates instantly. I did a test of the variables passed to the thread by taking a hash of the three byte arrays and returning the results for comparison with the variables sent. This test verifies that data is correctly passed to the thread and that data can be returned. The API method runs correctly on the main thread.


Imports VB = Microsoft.VisualBasic
Imports CryptoSysAPI
Imports System.IO
Imports System
Imports System.Threading

Public Class ThreadWrapper

    Public Sub New(ByRef abData() As Byte, _
                                 ByRef abKey() As Byte, _
                                 ByVal n As Integer, _
                                 ByRef abInitV() As Byte)

        Initialize data passed to ThreadWrapper.
        ReDim abData1(0)
        ReDim abData2(0)
        ReDim abData3(0)

        abData1 = abData
        abData2 = abKey
        n1 = n
        abData3 = abInitV

        thread = New System.Threading.Thread(AddressOf Body)
    End Sub

    Public Sub start()
        Me.thread.Start()
    End Sub

    Public Sub join()
        Me.thread.Join()
    End Sub

    Public Sub Body()

        '' The API call.
        Me.abData1 = Blowfish.Encrypt(Me.abData1, Me.abData2, n1, Me.abData3)

    End Sub

    '' The definitions of the data passed to ThreadWrapper Class.
    Private abData1() As Byte
    Private abData2() As Byte
    Private n1 As Integer
    Private abData3() As Byte

    Public thread As System.Threading.Thread
End Class


'' This is the call to the ThreadWrapper class to create a new thread and start the thread.
'' All inputs are byte array except Mode.CBC which is an integer.

Public Class Protect

        Public Function Encyrpter(Inputs....) as Integer

                Dim tw As New ThreadWrapper(X_abData1, _
                                            X_abDerivedKeyHex, _
                                            Mode.CBC, _
                                            abInitVector, _
                                            X_abData3)
                tw.start()
                tw.join()

        End Function '' Encrypter.

End Class '' Protect.





VSNetVbHarry



VSNetVbHarry


这篇关于将参数传递给线程化的LongRunningProcess的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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