【问题标题】:how to use string in multiple threads如何在多个线程中使用字符串
【发布时间】:2014-01-18 11:31:56
【问题描述】:

所以我需要让我的 IP 字符串被我的程序的 2 个线程使用。我不太了解课程和空位,但当时我的情况是这样的:

    static void Main(string[] args)
    {
        string IP = "127.0.0.1"
    }

我想在另一个线程中使用它:

    static void th1T()
    {
        while (true)
        {
            var ping = new Ping();
            ping.Send(IP);
        }
    }

我怎样才能让它发挥作用?我知道我做错了什么,但不知道我应该改用什么。

【问题讨论】:

  • 我会为接受 IP 字符串的调用方法使用一个参数。看看这是否适合你。
  • 如何创建新线程?您可以将此问题作为创建带有参数的新线程的参考:stackoverflow.com/questions/1195896/threadstart-with-parameters
  • 我知道如何创建一个新线程,这不是问题所在。我只是没有把它复制到问题中
  • 对,但是你的问题不是你不知道如何访问线程中的IP变量吗?这个问题告诉你怎么做。此外,您可以查看 Ian P 或 Darin Dimitrov 的答案。
  • “我不太了解类和空位”——我并不是要冒犯,但听起来你在爬之前就想跑。在尝试更复杂的主题(如多线程)之前,应先了解语言特性(如类和返回类型)。

标签: c# multithreading ip ping void


【解决方案1】:

第一个问题是IP 的作用域是方法Main。如果你真的想分享它,你需要在 th1T 可以到达的地方声明 IP

static string IP = "127.0.0.1"

static void Main(string[] args)
{
    // do some work and start th1T()
}

static void th1T()
{
    while (true)
    {
        var ping = new Ping();
        ping.Send(IP);
    }
}

即使th1T 在不同的线程上运行,您也可以在此处访问IP。不过还有其他一些选项,例如在线程启动时注入 IP 到th1T。为此,您必须将th1T 的签名更改为:

static void th1T(object data)

你必须稍微修改一下代码:

static void th1T(object data)
{
    while (true)
    {
        var ping = new Ping();
        ping.Send(data as string);
    }
}

然后你可以像这样在另一个线程上启动它:

Thread newThread = new Thread(th1T);
newThread.Start(IP);

线程是一个非常主观的主题。如果您从另一个线程引用的值是只读,就像在您的示例中一样,并且它仅由控制器(开始工作的类)设置一次,那么共享该值是绝对有效的线程之间的变量。然而,许多人会为此争论不休。

关于这个问题,我们只能笼统地说。例如,一般更适合注入值以避免竞争条件和死锁。但同样,这真的取决于你对价值所做的事情。如果您从一个线程读取由另一个线程设置的标志,则无法注入该值。在这种情况下,您必须安全地同步该值。

没有必要继续,因为你看到兔子洞只会越来越深。

【讨论】:

  • 我认为这不是明智之举;也许只是作为一个快速修复。当然,这在很大程度上取决于程序。
  • @OMer Obaid,当 Ken 评论时,这个答案中的解决方案只是让 IP 成为全局变量。
  • @SeanCogan 是的,是的。所以 Omer 的原因是默认情况下应该避免全局变量,以实现可维护的架构和设计(这对我来说是 令人愉快,顺便说一句)。由于第二种解决方案,我现在确实删除了我的反对票,但我仍然认为我所说的内容也应该在答案中注明(这是不可取的)。
  • @Ken,很明显我理解你的立场,但我确实为你解决了这个问题。正如我所说,我们只能笼统地说,因为绝对存在 注入值 不是解决方案的情况。有些时候你必须保持值同步,老实说,有些时候你不需要。
  • @MichaelPerrenoud 完全同意。你的精彩回答得到了我的投票:)。
【解决方案2】:

你应该重构你的方法来接受一个字符串作为参数:

static void th1T(string IP)
{
    while (true)
    {
        var ping = new Ping();
        ping.Send(IP);
    }
}

当你调用方法时,传入你的 IP。

你想要做的相当于一个全局变量,这通常不是一个好主意。

您可以使用的另一种方法是使用静态类来存储值:

public static class Values
{
    string IP { get; set; }
}

在你的方法中:

static void th1T()
{
    while (true)
    {
        var ping = new Ping();
        ping.Send(Values.IP);
    }
}

我想补充一点,这种方法可能会产生几个问题。这样做可能不是最佳做法。

【讨论】:

  • 在这一点上它说它需要在 Values.IP 上参考
【解决方案3】:

您尚未展示如何启动线程,但在所有情况下,您都可以将字符串作为参数发送到线程。例如,如果您手动生成一个新线程,您可以将其作为参数传递给 Start 方法:

static void Main(string[] args)
{
    string IP = "127.0.0.1"
    Thread t = new Thread(th1T);
    t.Start(IP);
} 

static void th1T(object value)
{
    // The value parameter will contain the IP here
    string ip = (string)value;
    while (true)
    {
        var ping = new Ping();
        ping.Send(ip);
    }
}

请注意th1T 方法现在如何接受一个对象参数,您可以将其转换回正在传递的值。在此示例中,我们传递了一个简单的字符串值,但您可以传递任意复杂的对象。

如果您使用的是任务,您还可以传递参数:

static void Main(string[] args)
{
    string IP = "127.0.0.1"
    Task.Factory.StartNew(th1T, IP);
} 

static void th1T(object value)
{
    // The value parameter will contain the IP here
    string ip = (string)value;
    while (true)
    {
        var ping = new Ping();
        ping.Send(ip);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-19
    • 1970-01-01
    • 2017-05-30
    • 2021-12-10
    • 2015-07-09
    • 1970-01-01
    相关资源
    最近更新 更多