Увы не могу понять как передавать между классами структуру.
Знаю, можно передавать между классами в классе общие ресурсы (переменные и т.д.), НО я бы именно хотел узнать возможна ли передача именно структур между классами.
Вот код :
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Collections.Concurrent;
using System.Threading.Tasks;
// передать структуру в поток и если че выключить её
public struct SPEED
{
public int speed; //скорость
}
public class Program
{
static void Main(string[] args)
{
// !!! вот тут пытасюсь заполнить и передать структуру
SPEED speed_t = new SPEED();
speed_t.speed = 1;
// Запускаем задачи
// !!! вот тут ошибка
Task task1 = new Producer("Передающая задача", speed_t).Task;
Task task2 = new Consumer("Принимающая задача").Task;
// И ждем их завершения
Task.WaitAll(task1, task2);
Console.WriteLine("Все задачи завершены.");
// Ну и чтобы окошко сразу не закрылось
Console.ReadKey();
}
}
static class SharedRes
{
// та самая блокирующая коллекция
public static BlockingCollection<string> Data { get; } = new BlockingCollection<string>();
// содержит отменяющий токен, необходимый для прерывания ожидания блокирующей коллекции
public static CancellationTokenSource Cts { get; } = new CancellationTokenSource();
}
public class Producer
{
public Task Task { get; }
public string Name { get; }
public Producer(string name, ref SPEED speed_t)
{
Console.WriteLine("скорость равна {0}", speed_t.speed);
Name = name;
Task = Task.Run(Run(speed_t.speed));
}
bool Examples(int i)
{
if(i==1)
{
return true;
}
return false;
}
void Run(int i)
{
if (Examples(i) == false)
{
Console.WriteLine("Чепушня не отработала.");
return 0;
}
ProcessStartInfo startInfo = new ProcessStartInfo()
{
FileName = "ping",
Arguments = "www.ya.ru",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
};
using (var pingProcess = new Process())
{
pingProcess.StartInfo = startInfo;
pingProcess.OutputDataReceived += OutputDataReceived;
pingProcess.Start();
pingProcess.BeginOutputReadLine();
pingProcess.WaitForExit();
}
SharedRes.Cts.Cancel(); // отправить сигнал в BlockingCollection, что пора заканчивать
Console.WriteLine(Name + " завершает работу.");
}
private static void OutputDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine("Мы в задаче один");
SharedRes.Data.Add(e.Data);
// немного упростил запись в лог
File.AppendAllText("log.txt", e.Data + Environment.NewLine);
}
}
class Consumer
{
public Task Task { get; }
public string Name { get; }
public Consumer(string name)
{
Name = name;
Task = Task.Run(Run);
}
void Run()
{
try
{
// Здесь коллекция ждет, пока не появится новый элемент или пока токен не получит отмену
foreach (string s in SharedRes.Data.GetConsumingEnumerable(SharedRes.Cts.Token))
{
Console.WriteLine("Мы в задаче два");
Console.WriteLine(s);
}
}
catch (OperationCanceledException ex)
{
// Здесь можно вообще ничего не делать
Console.WriteLine("Ожидание новых данных прервано: " + ex.Message);
}
Console.WriteLine(Name + " завершает работу.");
}
}
Увы выдаёт мне множество ошибок :(
lovla_terminal10.cs(23,22): error CS1502: The best overloaded method match for `Producer.Producer(string, ref SPEED)' has some invalid arguments
lovla_terminal10.cs(48,12): (Location of the symbol related to previous error)
lovla_terminal10.cs(23,56): error CS1620: Argument `#2' is missing `ref' modifier
lovla_terminal10.cs(52,21): error CS1502: The best overloaded method match for `System.Threading.Tasks.Task.Run(System.Action)' has some invalid arguments
/usr/lib/mono/4.5/mscorlib.dll (Location of the symbol related to previous error)
lovla_terminal10.cs(52,25): error CS1503: Argument `#1' cannot convert `void' expression to type `System.Action'
lovla_terminal10.cs(69,13): error CS0127: `Producer.Run(int)': A return keyword must not be followed by any expression when method returns void
Compilation failed: 5 error(s), 0 warnings
new Producer("Передающая задача", ref speed_t)все модификаторы надо явно указывать – Grundy May 17 '20 at 16:31