@mIka01

Отдать значения в поток и вернуть результат выполнения?

Здраствуйте, впервые работаю с потоками. У меня вопрос прост, но я его не могу найти в интернете.
Как передать массив int[] в поток, где выполнится некоторый код, после выполнения поток должен вернуть другой массив.
Как это сделать ?

И как при необходимости завершить поток из другого места, условно из другого потока.

Заранее благодарю за ответ.
  • Вопрос задан
  • 690 просмотров
Решения вопроса 1
1. Сначала убедись, что для твоей задачи действительно нужен именно поток, а не какая-то более высокоуровневая абстракция, например Task
2. Если всё-таки поток, то есть два варианта:
1. Через обратный вызов. В конце своей работы, в потоке нужно вызвать какой-то метод, который будет обрабатывать результат.
using System.Threading;

var data = new int[1]; // Какие-то данные

var thread = new Thread(() => {
  var result = data.Length; // Какие-то ужасно сложные вычисления
  HandleResult(result); // Это можно передать как параметр-делегат, но тут мы будем конкретный метод использовать
});
thread.Start(); // Стартуем
// Какие-то дела
thread.Join(); // Всё равно надо по-хорошему дождаться окончания работы потока
void HandleResult(int value) {
  Console.WriteLine(value);
}

2. Через Join и какую-то общую переменную или поле.
using System.Threading;

var data = new int[1]; // Какие-то данные
var result = 0; // Какой-то результат (инициализируем значением по-умолчанию)
var thread = new Thread(() => {
  result = data.Length; // Какие-то ужасно сложные вычисления
});
thread.Start(); // Стартуем
// Какая-то работа
thread.Join(); // Дожидаемся окончания работы потока
Console.WriteLine(result); // Используем результат работы
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
twobomb
@twobomb
Никак, просто обращайтесь из одного потока к другому напрямую или через Invoke. Если напрямую и боитесь что доступ может производится в один момент из двух потоков, используйте lock перед записью.
Для отмены реализуйте механизм CancellationToken
Ответ написан
Комментировать
freeExec
@freeExec
Участник OpenStreetMap
В такс можно передать объект. А объектом может выступать что угодно. Соответственно это и будет вашей точкой обмена, вы туда кладёте исходные данные, такс результаты. Через cancellationTokenSource можно завершить таск преждевременно. Ну а Sync используется если у вас несколько поток и им необходимо синхронизироваться межу собой или например вы хотите забрать промежуточные результаты.
public class TaskState
    {
        public CancellationToken CancellationToken;
        public int[] Input;
        public int[] Output;
        public object Sync;
    }

    private static void TaskBodyPoolQueue(object state)
    {
            var taskState = (TaskState)state;

            do
            {
            // Calculate
            } while (!taskState.CancellationToken.IsCancellationRequested);
            taskState.Output = ...
    }

            taskStateProgress = new TaskState()
            {
                Input = ...,
                CancellationToken = cancellationTokenSource.Token,
                Sync = new object()
            };
            for (int i = 0; i < 6; i++)
                ThreadPool.QueueUserWorkItem(new WaitCallback(TaskBodyPoolQueue), taskStateProgress);
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы