在背景线程问题上使用方法

发布于 2025-02-07 14:09:13 字数 1196 浏览 4 评论 0 原文

我目前正在学习C#,并且在将其重新分配给新方法之前在后台线程上运行一个问题(我有一个在后台工作的套接字,因为我只能获得 通常允许使用每个套接字地址(协议/网络地址/端口)的一个用法例外)。我将 tcpthread 设置为 null ,并认为它会杀死其中的所有内容,但我想它的插座仍然活在堆中。

如果挂起,这是执行重新启动TCP线程动作。

private static void startTCPServer()
{
    viewModel.stopTCPServer(); // I need to be able to call this on the existing tcpThread
    tcpThread = null;
    tcpThread = new Thread(new ThreadStart(viewModel.startTCPServer));
    tcpThread.Priority = ThreadPriority.AboveNormal;
    tcpThread.IsBackground = true;
    tcpThread.Start();
}

另外,这是正确的方法吗?

编辑: 这是使用任务导致相同问题的:

    private static void startTCPServer()
    {
        tokenSource = new CancellationTokenSource();

        Task.Run(() =>
        {
            while (true)
            { 
                if (tokenSource.Token.IsCancellationRequested)
                {
                    viewModel.stopTCPServer();
                    break;
                } else
                {
                    viewModel.startTCPServer();
                    break;
                }
            }
        }, tokenSource.Token);
    }

I'm currently learning C# and having an issue in running a method on a background thread before reassigning it to a new one (I have a socket that's working in the background that I need to close as I'm getting the Only one usage of each socket address (protocol/network address/port) is normally permitted exception). I set the tcpThread to null and thought it would kill everything inside it but I guess it the socket is still alive in heap.

This is to perform a restart TCP thread action if it hangs.

private static void startTCPServer()
{
    viewModel.stopTCPServer(); // I need to be able to call this on the existing tcpThread
    tcpThread = null;
    tcpThread = new Thread(new ThreadStart(viewModel.startTCPServer));
    tcpThread.Priority = ThreadPriority.AboveNormal;
    tcpThread.IsBackground = true;
    tcpThread.Start();
}

Also, is this the right approach?

EDIT:
Here's using Task which results in the same issue:

    private static void startTCPServer()
    {
        tokenSource = new CancellationTokenSource();

        Task.Run(() =>
        {
            while (true)
            { 
                if (tokenSource.Token.IsCancellationRequested)
                {
                    viewModel.stopTCPServer();
                    break;
                } else
                {
                    viewModel.startTCPServer();
                    break;
                }
            }
        }, tokenSource.Token);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

め七分饶幸 2025-02-14 14:09:13

您需要从背景线程中合作才能正确关闭它。 。典型的方法是使用取消token来向背景线发信号以关闭。 伪代码中

public void OnBackgroundThread();
  // create any resources in a using block at the start of the method
  while(!cts.Token.IsCancellationRequested){
    
     // Call some blocking method with a timeout
     RunBlockingOperation(timeout);
     // Better if the method accepts a cancellationToken
     RunBlockingOperation(cts.Token);
     // Or if there is an async, non blocking method
     // needs async keyword in method signature
     await RunAsyncOperation(cts.Token); 
  }

}

// Start thread
cts = new CancellationTokenSource();
task = Task.Factory.StartNew (OnBackgroundThread,TaskCreationOptions.LongRunning);

// Shut down thread
cts.Cancel();
// You need to await/wait for the background thread to complete
// Otherwise there is a risk that the resources are not released
// when the shutdown method has completed
await task; 

在评论中提到的 ,您应该使用任务而不是原始线程。这使同步工作变得更容易。

但是,如果您仍在学习c#,则应该花一些时间学习线程安全。这是一个相当大且复杂的话题,但是在涉及多个线程时,了解危险是批判性的。没有这些知识,您可能会导致可能很难找到和复制的错误。

如果您的目标是简单地进行两台计算机进行通信,我建议您使用比RAW TCP更高的级别协议/库。这样,您可能会尽快获得一个工作解决方案,并减少引起错误的机会。根据您的确切需求有很多选择,请参见 https://softwarerecs.stackexchange.com/

You need cooperation from the background thread to shut it down correctly. The reasoning is explained in greater detail in What's wrong with using Thread.Abort(). A typical approach for this would be to use a cancellationToken to signal the background thread to shut down. In pseudo code

public void OnBackgroundThread();
  // create any resources in a using block at the start of the method
  while(!cts.Token.IsCancellationRequested){
    
     // Call some blocking method with a timeout
     RunBlockingOperation(timeout);
     // Better if the method accepts a cancellationToken
     RunBlockingOperation(cts.Token);
     // Or if there is an async, non blocking method
     // needs async keyword in method signature
     await RunAsyncOperation(cts.Token); 
  }

}

// Start thread
cts = new CancellationTokenSource();
task = Task.Factory.StartNew (OnBackgroundThread,TaskCreationOptions.LongRunning);

// Shut down thread
cts.Cancel();
// You need to await/wait for the background thread to complete
// Otherwise there is a risk that the resources are not released
// when the shutdown method has completed
await task; 

As mentioned in the comments, you should be using Tasks and not raw threads. This makes it a bit easier to synchronize the work.

However, if you are still learning c# you should spend some time studying thread safety. This is a rather large and complicated topic, but it is critical to know about the dangers whenever multiple threads are involved. Without this knowledge you will likely cause bugs that may be very difficult to find and reproduce.

If your goal is to simply make two computers communicate I would recommend using some higher level protocol/library than raw tcp. This way you will likely get a working solution much sooner with a reduced chance of causing bugs. There are plenty to choose from depending on your exact needs, see https://softwarerecs.stackexchange.com/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文