Как реализовать обмен данными между основным циклом и потоками? Допустим есть такой псевдокод Пример:
namespace First
{
public class Test
{
public static string Outout1 = string.Empty;
private static System.Threading.Thread SThread;
public static string Func1()
{
pass;
}
public static void GetTimeNow()
{
for(;;){
Outout1 += Func1();
System.Threading.Thread.Sleep(4000);
}
}
public static string GetTimeNow2()
{
pass;
}
private static void RunThread()
{
if (SThread == null || SThread.ThreadState != System.Threading.ThreadState.Running)
{
SThread = new System.Threading.Thread(GetTimeNow);
SThread.Start();
}
}
public static void MainFunc()
{
for(;;){
Outout1 += GetTimeNow2();
RunThread() ;
System.Threading.Thread.Sleep(5000);
}
}
}
}
Запускается главная функция MainFunc
в бесконечный цикл в этом цикле вызываем функцию GetTimeNow2
. Которая возвращает нам данные в переменную Outout1
.
Далее запускает функцию RunThread
которая запускает функцию GetTimeNow
в отдельном потоке.
В функции GetTimeNow
бесконечный цикл, и в нем вызывается Func1
, которая пишет данные в Outout1
.
Вопрос будут ли всегда корректные данные в переменной Outout1
, а именно будут ли видны данные от GetTimeNow2
и GetTimeNow
и если обнулить ее в конце цикла она так же обнулится в GetTimeNow
которая запущена в отдельном потоке?
Пример:
for(;;){
Outout1 += GetTimeNow2();
RunThread();
System.Threading.Thread.Sleep(5000);
Outout1 = "";
}
Подскажите пожалуйста как правильно реализовать данный способ , что бы можно было работать с переменной Outout1 как в основном цикле так и в цикле который запущен в отдельном потоке? и как сделать сделать если запустить не 1 поток а 2-5 Пример:
for(;;){
Outout1 += GetTimeNow2();
RunThread();
RunThread1();
RunThread2();
System.Threading.Thread.Sleep(5000);
Outout1 = "";
}
Как один из вариантов - можно использовать асинхронное программирование с использованием ключевых слов async и await. Результат вы получите тот же без необходимости создавать потоки и без риска получить состояние гонки из за разделяемой переменной. Вот псевдокод:
public class MyTestClass
{
public static string outputString = String.Empty;
public static string GetFirstString()
{
return "world";
}
public static string GetSecondString()
{
return "!!!";
}
public static async Task FirstTimer()
{
for(int i = 0; i < 10; i++)
{
outputString += GetFirstString();
await Task.Delay(50);
}
}
public static async Task SecondTimer()
{
for (int i = 0; i < 10; i++)
{
outputString += GetSecondString();
await Task.Delay(50);
}
}
public static string GetStartString()
{
return "Hello ";
}
public static async Task MyMain()
{
for (int i = 0; i < 1 ; i++)
{
outputString += GetStartString();
await FirstTimer();
await SecondTimer();
await Task.Delay(500);
Console.WriteLine(outputString);
outputString = String.Empty;
}
}
Проверить его можно или в UnitTest-е Например так :
[TestMethod]
public async Task TestAsyncLoop()
{
await MyTestClass.MyMain();
}
Либо в консольном приложении
public static async Task Main()
{
await MyTestClass.MyMain();
}
Примечание 1: в консольном приложении применить async к функции Main появилась только с версии компилятора C# 7.1 В других версиях компилятора нужно использовать
public static void Main ()
{
MyTestClass.MyMain().Wait();
}
Примечание 2: в приложениях с графическим интерфейсом нужно использовать асинхронные методы с учетом контекста выполнения, что бы не попасть в состояние взаимоблокировки.
Как меняется крипторынок и к чему готовиться владельцам криптообменников
Есть вот такой код простого конвертера валют(SOM - это валюта Кыргызстана)
При открытии сайтов должны игнорироваться x-frame-options (запрет на открытие некоторых страниц в iframe, в браузерах решается установкой мини-плагина)
Проблема следующая: создан проект wpf (с использованием фреймов и страниц)В отладке все стабильно работает, но после установки запускается...