如何将ref参数传递给线程 [英] How to pass ref parameter to the thread

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

问题描述

大家好!
我想将引用参数传递给线程.
代码段:

Hi all!
I want to pass reference parameter to thread.
Code snippet:

private void Start(ref TcpClient handler)
{
  ClientThread = new Thread(delegate() { HandleClientComm(ref handler); });
  ClientThread.Start( handler);
}


但这写信给我:
无法在匿名方法,lambda表达式,查询表达式中使用ref或out参数"

还是如何保留对变量的引用(不是值)?

谁能帮助我?


But it writes to me:
"Cannot use ref or out parameter inside an annonymous method, lambda expression, query expression"

Or how to keep reference(not value) to the variable?

Who could help me?

推荐答案

好问题.首先要考虑:您真的需要吗?有更好的方法:包装线程并传递this.之后,线程访问该类中的任何内容.那不是很好吗?

Good question. First to think about: do you really need to? There is much better method: to wrap a thread and pass this. After that, the thread accesses anything in the class. Isn''t that nice?

internal class ThreadWrapper {

    internal ThreadWrapper(/*..*/) {
        /* pass whatever needed from out side */
        Thread = new System.Threading.Thread(Body); //don't tell my it is illegal!
    } //ThreadWrapper

    internal void Start() { this.Thread.Start(); }
    internal void Abort() { this.Thread.Abort(); }

    //and so on...

    void Body() {
        if (this.SomeByRefParameter == null) //can read
            this.SomeByRefParameter = new System.Text.StringBuilder(); //can modify
        //why? because this member is non-static, "this" parameter is used
        //...
    } //Body

    object SomeByRefParameter;
    System.Threading.Thread Thread;

} //class ThreadWrapper



你能看到发生了什么吗?我们设法将非静态(实例)方法作为线程的起点.由于这是一个实例方法,因此Body具有名为this的隐藏参数.它用于传递ThreadWrapper的实例.有了实例后,就可以访问该实例的任何成员(如SomeByRefParameter的示例所示).您可以从外部访问包装器的其他方法,并使用按引用方法的按值传递任何参数.不要忘记使用同步原语,例如lock.

不要害怕这种启动线程的方法没有很好的文档说明,但是它比带有参数的起点可靠得多,因为不需要类型转换.

—SA



Can you see what''s going on? We managed to run non-static (instance) method as a thread start point. As this is an instance method, Body has hidden parameter called this; it is used to pass an instance of the ThreadWrapper. As we have the instance, we can access any members of this instance (shown on example of SomeByRefParameter). You can have other methods of the wrapper accessible from outside and pass any parameter using by value of by reference methods. Don''t forget to use synchronization primitives, such as lock.

Don''t be afraid; this method of starting thread is not very well documented, but it is much more reliable than starting point with parameter because type casting is not required.

—SA


问题是您试图将ref变量传递给匿名方法.这就是问题所在的原因:
The problem is that you are attempting to pass a ref variable to an anonymous method. Here is why that is a problem:
Start(ref handler);
handler.DoSomething();
// handler could change here.
handler.DoSomething();


如果您通过引用传入函数实例,并且该函数将该引用变量传递给匿名方法,则该匿名方法可以在另一个线程中执行,这将导致变量引用在不确定的时间改变(例如当到达以上代码中的注释时).由于仅当您从方法调用中返回时,传递"ref"只能更改变量引用,因此此功能无效.这是您可以解决该问题的一种方法(使用临时变量):


If you pass in an instance by reference to your function and that function passes that reference variable to an anonymous method, that anonymous method could then be executed in a different thread, which would cause the variable reference to change at an undetermined time (such as when the comment in the above code is reached). Since the passing by "ref" is only supposed to change the variable reference when you return from the method call, this functionality is invalid. Here is one way you might get around that (uses a temporary variable):

private void Start(ref TcpClient handler)
{
  var handler2 = handler;
  ClientThread = new Thread(delegate() { HandleClientComm(ref handler2); });
  ClientThread.Start();
  // ClientThread.Join();   // Uncomment this line to ensure HandleClientComm has finished running.
  handler = handler2; // handler2 may or may not have changed by now.
}


这可能会导致意外的副作用,但是至少您的代码可以编译.


That may cause unintended side effects, but at least your code will compile.


^ ]会给您一个想法.
Pass Ref Parameter[^] will give you an idea.


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

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