Как запустить переменное количество методов в зависимости от ввода пользователя в Windows Forms - PullRequest
0 голосов
/ 09 января 2019

Я борюсь с концепцией, описанной ниже:

Пользователь проверяет x из 5 флажков с типом измерений, а затем нажимает кнопку «RUN». На «RUN» OnClick () я создаю объект класса Measure.

class Measure
{
    string measure_type;
    SendCommandToArduino(string nameOfMeasurement)
    ...
}

Мне нужно запустить эти выбранные методы ПОСЛЕДОВАТЕЛЬНО (они НЕ МОГУТ работать асинхронно, потому что они используют последовательный COM).

Я жестко запрограммировал что-то вроде этого:

void Method1()
{
    measurement.SendCommandToArduino("tetnienie");
}

void Method2()
{
    measurement.SendCommandToArduino("jasnosc");
}

tPomiar1 = new Thread(Method1);
tPomiar1.Start();
tPomiar1.Join();
pomiar.DrawGraphTetnien(tetnienie_Chart);
tPomiar2 = new Thread(Method2);
tPomiar2.Start();
tPomiar2.Join();
MessageBox.Show("Done all measurements!");

Не удивительно - это сработало. Но:

  1. Я до сих пор не знаю, как связать количество отмеченных флажков с количеством методов, запускаемых в этих потоках. Может быть, мне следует жестко закодировать MethodX для всех измерений, а затем запустить потоки из какого-нибудь списка list_of_threads?

  2. Потоки излишни для этой цели (я полагаю), потому что самое длинное измерение занимает около 10 секунд ... Есть ли другой способ? ThreadPool, Задачи, async / await? Я совершенно новичок в многозадачности / потоках

Я тоже попробовал что-то подобное, но я не закончил это решение, оно было слишком хардкорным:

    List<Thread> list_of_threads= new List<Thread>();
    List<Action> measureToDo = new List<Action>();
    // link those additions with checkboxes
    measureToDo.Add(Method1);
    measureToDo.Add(Method2);
    measureToDo.Add(Method3);

    int i = 0;
    foreach (Action action in measureToDo)
    {
        //substring this one to get method's name!
        string methodName = action.Method.Name.ToString());
        methodName = methodName.Substring(4,6) // limit of 9 methods here haha
    }

    foreach (var item in measureToDo )
    {
        RunThread(item.Method.Name.ToString());
    }

    void RunThread(Action a)
    {
        Thread t;

        t = new Thread(new ThreadStart(a.Method.Name)).Start();
    }

Для параметра measure_type я создал 5-битную строку -> «1», если был установлен флажок для этой позиции. "01000" / "10011" и т. Д.

Заранее благодарим Вас за все советы / подсказки! :)

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Возможно, вы слишком усложняете вещи, и простое решение было бы прекрасно.

Вы можете использовать свойство Control.Tag и добавить имя (в виде строки) меры к каждому из ваших флажков. Затем вы можете перечислить свои флажки, посмотреть, какие из них отмечены, и получить список строк с названиями мер, которые вам нужно выполнить.

Тогда вам нужен единственный метод для выполнения ваших мер. Он должен перечислить список и иметь переключатель для сопоставления меры с методом:

void ExecuteMeasures(List<string> measures) 
{
    foreach (string measure in measures)
    {
        switch (measure)
        {
            case "Measure 1": MeasureMethodOne(); break;
            // and so on...
        }
     }
 }

Тогда вам не нужно запускать каждый метод меры в отдельном потоке, потому что вы хотите, чтобы они выполнялись последовательно. Вам нужно только запустить ExecuteMeasureMethod в отдельном потоке. Если он запускается в течение нескольких секунд, отдельный поток - это нормально. Тем не менее, чтобы сохранить порядок, используйте долгосрочное задание:

var listOfMeasures = new List<string>();
//Populate your list from the selection of check boxes
Task t = Task.StartNew ( ()=> ExecuteMeasures(listOfMeasures), TaskCreationOptions.LongRunning);
await t;
0 голосов
/ 09 января 2019

Вот мое решение: 1. Определите массив действий для хранения ваших методов 2. Получить значения отмеченных элементов (значение checkbox1 равно 0 и т. Д.) В качестве индексов массива 3. Вызвать соответствующий метод в массиве.

Коды - это что-то вроде:

public static void Main()
{
    Action[] actions = new Action[5];
    actions[0] = Method1;
    actions[1] = Method2;

    string checkedValue = "1";
    actions[int.Parse(checkedValue) - 1].Invoke();
}

static void Method1()
{
    Console.WriteLine(1);
}

static void Method2()
{ }

Или вы можете упростить код, как показано ниже:

public static void Main()
{
    Action[] actions = new Action[5];
    actions[0] = ()=> { Console.WriteLine(1); };
    actions[1] = ()=> { Console.WriteLine(2); };

    string checkedValue = "1";
    actions[int.Parse(checkedValue) - 1].Invoke();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...