从另一个线程和名称空间取消正在运行的任务

时间:2019-06-09 18:55:05

标签: task cancellation cancellationtokensource cancellation-token

我有一个Windows服务项目(使用TopShelf nuget包),该项目会自动启动运行TCP Server的任务。在同一个Visual Studio解决方案中,我还有一个提供用户界面的Windows Forms应用程序。

Windows服务用于在Windows最初启动时启动TCP服务器的运行任务,但是我需要对TCP Server进行一些其他控制,即Windows Forms App中提供的停止和启动功能。这主要是因为如果用户需要更改端口或侦听IP地址,则当前他们必须先停止Windows服务,然后才能进行更改。 Windows Forms App提供了一个用户界面,他们可以启动和停止运行该服务器的任务,以便他们可以进行所需的更改。

我需要一个解决方案,如果Windows服务已经启动了运行任务,则需要能够从Windows窗体应用程序中取消运行任务。

我遇到的问题是Windows Forms App不知道取消令牌源对象,因为它是从Windows服务项目(在不同的线程和不同的名称空间中)创建的,因此当我尝试运行Windows Form应用程序中应该取消正在运行的任务的方法,我得到“对象引用未设置为对象的实例”

我在下面提供了一些示例代码,但是我已经知道它显然是错误的...

请帮助

我查看了论坛How to cancel a task from different class 但是解释并没有给我足够的细节,以至于无法完全理解他们在说什么,并且可能与我的环境不相关。

第一部分是Windows服务项目中的代码:

 public class SoftwareModules
{
    private static readonly log4net.ILog log = log4net.LogManager.GetLogger("SystemLogsRollingFileAppender");

    // Create an instance of a CancellationTokenSource that will be used to
    // stop the system modules from running.
    public static CancellationTokenSource cancelSource;

    /// <summary>
    /// 
    /// </summary>
    public static void StartupSoftwareModules()
    {
        // Temp config
        string inboundEncodingType = "ASCII";
        string outboundEncodingType = "ASCII";
        string inboundIpAddress = "127.0.0.1";
        string inboundLocalPortNumber = "10001";
        string outboundIpAddress = "127.0.0.1";
        string outboundLocalPortNumber = "10002";
        string selectedMapping = "maping1";

        cancelSource = new CancellationTokenSource();

        // This is the class that holds the server that I want to start from the windows service.
        MOD_TcpServerTcpServer mOD_TcpServerTcpServer = new MOD_TcpServerTcpServer();
        mOD_TcpServerTcpServer.TcpServerIN(inboundEncodingType, outboundEncodingType, inboundIpAddress, inboundLocalPortNumber, selectedMapping, cancelSource.Token);
        mOD_TcpServerTcpServer.TcpServerOUT(outboundIpAddress, outboundLocalPortNumber, selectedMapping, cancelSource.Token);
    }

    /// <summary>
    /// 
    /// </summary>
    public static void ShutdownSoftwareModules()
    {
        // Call the cancelleation of the associated thread that is running the system maping that needs to be shutdown.
        cancelSource.Cancel();

        //log.Info("System Mapping: [" + selectedMapping + "] has shutdown");
    }
}

下一部分是我从Windows Forms Application获得的按钮控件,该控件位于同一visual studio解决方案中,并且已经引用了“ using WindowsService”。在顶部。

 public partial class MainWindowForm : Form
 { 
    private void Button1_Click(object sender, EventArgs e)
    {
        SoftwareModules.ShutdownSoftwareModules();
    }
 }

0 个答案:

没有答案