Отмена запущенной задачи из другого потока и пространства имен - PullRequest
0 голосов
/ 09 июня 2019

У меня есть проект службы Windows (использующий пакет nuget TopShelf), который автоматически запускает задачу для запуска TCP-сервера.В том же решении Visual Studio у меня также есть приложение Windows Forms, которое предоставляет пользовательский интерфейс.

Служба Windows используется для запуска задачи запуска для сервера TCP при первом запуске Windows, однако мне нужны некоторые дополнительныеуправление сервером TCP, т.е. функции остановки и запуска, доступные в приложении Windows Forms.Это связано прежде всего с тем, что если пользователю необходимо изменить порт или прослушиваемый IP-адрес, ему в настоящее время придется остановить службу Windows, прежде чем он сможет внести изменения.Приложение Windows Forms предоставляет пользовательский интерфейс, с помощью которого они могут запускать и останавливать задачу, выполняющую этот сервер, чтобы они могли вносить необходимые изменения.

Мне нужно решение, при котором служба Windows уже запустила выполняемую задачу,Мне нужно иметь возможность отменить запущенную задачу из приложения формы Windows.

Проблема, с которой я сталкиваюсь, заключается в том, что приложение Windows Forms не знает об исходном объекте токена отмены, поскольку он был создан изпроект службы Windows (в другом потоке и в другом пространстве имен), поэтому, когда я пытаюсь запустить из приложения Windows Form метод, который должен отменить запущенную задачу, я получаю «Ссылка на объект не установлена ​​на экземпляр объекта»

Я поставил ниже пример кода, НО я уже знаю, что он явно неправильный ...

Пожалуйста, помогите

Я просмотрел форум Как отменить задачу из другого класса но объяснение не дает мне достаточно подробностей, чтобы полностью понять, о чем они говоряти может не относиться к моей среде.

Первый раздел - это код из Windows Service Project:

 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Приложение, которое находится в том же решении Visual Studio, и я уже ссылался на «использование WindowsService;»наверху.

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