Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
1 / 1 / 0
Регистрация: 02.10.2012
Сообщений: 110

Передача между процессами, разделяемая память?

03.04.2023, 10:45. Показов 3859. Ответов 35

Студворк — интернет-сервис помощи студентам
Хотел реализовать передачу данных между процессами (приложениями) - выбрал через разделяемую память - мне показалось самое простое (например https://metanit.com/sharp/articles/4.php). У меня форма (windowsForm) запускается из консольного приложения:
если на уровне консоли (консоль-консоль) - все работает,
если консоль - форма - разделяемая память не читается, как будто ее нет.

В чем проблема? Как передать информацию от консоли к форме (разные процессы), возможно через разделяемую память?

Добавлено через 1 час 46 минут
проверил между формами тоже работает,
п.с проблема консоль-форма
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
03.04.2023, 10:45
Ответы с готовыми решениями:

Windows API и передача сообщений между процессами посредством SEND_MESSAGE
Здравствуйте, уважаемые форумчане! Прошу помочь с передачей сообщений между процессами с помощью функции SEND_MESSAGE.В примерах в...

Передача классов между процессами через WCF
Есть ли способ передать класс из одного процесса в другой? То есть первый процесс пользуется классом второго процесса будто это его...

WS,WCF,WPF и передача данных между разными процессами (удалёнными\локальными)
Доброе утро. Задача стоит в условиях локальной работы! У меня есть WCF + WindowsService (имитация сервера) Есть WPF приложение...

35
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
04.04.2023, 02:56
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от IamRain Посмотреть сообщение
Мьютексы - только один поток. Как вам и нужно. То есть все у вас корректно.
Вы все дружно прикалываетесь? Что будет если у вас на входе уже есть возможность записать 10 строк, а приложение которое должно считывать еще и не запустилось? Как читающий поток, который крутится в вечном while знает что разблокировал именно пишуший поток, а не тупо опять пнулся цикл?

Если уже оооочень хочется чтобы в файле лежало не более одного сообщения, то тогда используют 2 read-write блокиратора. Общий подход такой

C#
1
2
3
4
5
6
7
8
9
10
11
//чтение
 
var readLocker = new Semaphore(0, 1, "read-name");
var writeLocker = new Semaphore(1, 1, "write-name");
 
while(reading)
{
readLocker.WaitOne();
// читаем
writeLocker.Release();
}

C#
1
2
3
4
5
6
7
8
9
10
11
//запись
 
var readLocker = new Semaphore(0, 1, "read-name");
var writeLocker = new Semaphore(1, 1, "write-name");
 
while(writing)
{
writeLocker.WaitOne();
// пишем
readLocker.Release();
}
В целом могу скинуть допилку прошлого примера под это дело, но это сродки обучать есть суп вилкой.

Цитата Сообщение от prajdziswet Посмотреть сообщение
"первый отсылает, второй ждет и читает". примерно так и происходит, решил проще чем городить сокеты,
Гляньте хотя бы Pipes Все эти "проще" выливаются в такое УГ, что потом не сколько решает задачи, сколько костылишь этот велосипед.
0
1 / 1 / 0
Регистрация: 02.10.2012
Сообщений: 110
13.04.2023, 14:42  [ТС]
Цитата Сообщение от Неко с ушами Посмотреть сообщение
Вы все дружно прикалываетесь? .
Не мог раньше ответить:
нет мы не прикалываемся, вы просто рекламируете семафоры (про то что я поблагодарил - имел введу, что мне их просто надо повторить)
1) Мьютекса как я и думал (так и IamRain написал), вполне достаточно!:
ConsoleApp1.zip
-проверка добавил в блок записи - уснуть на 600сек, все второй запуск ждет....
2) Твой пример, у тебя таже ошибка, что ты сам и писал = у тебя возможно чтение 0, или непонятно чего...
твои семафоры записи, блокирует поток записи при этом не блокирует чтение:
т.е допустим файл большой или ядро загружено и твой поток начинает тормозить, а в это время заходит поток чтения и начинает читаеть еще недописанный файл! - хотя скорее всего система просто збаит, выкинет исключение или не даст прочитать этот файл.
=> т.е ты сам совершил ту ошибку, которую так описвал..
3) насчет Pipes, спасибо- их вроде не встречал, в отличии от мьютексов/семафоров. За Pipes - еще раз спасибо.
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
13.04.2023, 16:51
Цитата Сообщение от prajdziswet Посмотреть сообщение
-проверка добавил в блок записи - уснуть на 600сек
На практике любой Sleep повод задуматься что у вас костыль.

Цитата Сообщение от prajdziswet Посмотреть сообщение
насчет Pipes
На всякий -- это то что вспомнилось/нагуглилось в первую очередь. На самом деле в .net столько решений (даже дефолтных), которые не шибко озвучиваются на всяких Metanit, что невольно начинаешь понимать зачем стоит читать документацию. Так что лишний раз пройтись в гугле (особенно по англ. ресурсам) будет не лишним.

Цитата Сообщение от prajdziswet Посмотреть сообщение
т.е допустим файл большой или ядро загружено и твой поток начинает тормозить, а в это время заходит поток чтения и начинает читаеть еще недописанный файл!
1. Сначала изучаем пример, а потом пишем что "на мой взгляд это ерунда". Мне тоже в свое время это показали, и первая мысль была "зачем?", но пораскинув ушами пришло понимание как это работает.
2. Второй поток не зайдет на "чтение/запись", так как первый выставляет блок. И наоборот. Т.е. одномоментно идет либо запись, либо чтение.
3. Два элемента для блокировки, чтобы нельзя было следующее
- записали
- опять записали, перетерев преведущее
- считали
writeLocker будет заблокирован до тех пор, пока не отработает чтение и наоборот

вот вам минимальный пример для проверки что такой подход работает
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
var buff = 0; //public buffer
var readLocker = new Semaphore(0, 1);
var writeLocker = new Semaphore(1, 1);
 
var count = 100000;
var writing = true;
 
//запись
var t1 = Task.Factory.StartNew(() => 
{
    for (var i = 0; i < count; i++)
    {
        writeLocker.WaitOne();
        buff = i;
        readLocker.Release();
    }
 
    writeLocker.WaitOne();
    writing = false;
    readLocker.Release();
});
 
//чтение
var t2 = Task.Factory.StartNew(() =>
{
    var i = 0;
    var result = new int[count];
    while (writing)
    {
        readLocker.WaitOne();
        if(!writing)
            break;
        result[i++] = buff;
        writeLocker.Release();
    }
 
    //проверка
    for (i = 1; i < count; i++)
    {
        if (result[i] == 0 || result[i] <= result[i - 1])
        {
            Console.WriteLine($"wrong {i} = {result[i]}");
        }
    }
});
 
Task.WaitAll(t1, t2);
Console.WriteLine("Completed!");
Console.ReadKey();
0
1 / 1 / 0
Регистрация: 02.10.2012
Сообщений: 110
13.04.2023, 19:34  [ТС]
Цитата Сообщение от Неко с ушами Посмотреть сообщение
На практике любой Sleep повод задуматься что у вас костыль....
Второй поток не зайдет на "чтение/запись", так как первый выставляет блок. И наоборот. Т.е. одномоментно идет либо запись, либо чтение.
1) => надо читать внимательнеее, слип -это только для проверки и показать, что мьютекс нормально справляется
2) по мне ты нагородил как раз костыль:
а)
C#
1
var writing = true;
- это локальная переменная, в своем потоке (точнее одного приложения) она своя (если не смотреть на задачи, то оно и не войдет на чтение)
б) тут неименованые светафоры и пример, только для своего потока


для конкретного примера оно нормально (для одного приложения). а если запустить паралельную программу локальные переменные будут свои...
______________________
Ладно не буду спорить, все равно спасибо...
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
13.04.2023, 21:10
Цитата Сообщение от prajdziswet Посмотреть сообщение
var writing = true;
Ппцц... окей, вот так может яснее будет?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var buff = 0; //public buffer
var readLocker = new Semaphore(0, 1);
var writeLocker = new Semaphore(1, 1);
 
var count = 100000;
 
//запись
var t1 = Task.Factory.StartNew(() => 
{
    for (var i = 0; i < count; i++)
    {
        writeLocker.WaitOne();
        buff = i;
        readLocker.Release();
    }
});
 
//чтение
var t2 = Task.Factory.StartNew(() =>
{
    var result = new int[count];
    for (var i = 0; i < count; i++)
    {
        readLocker.WaitOne();
        result[i++] = buff;
        writeLocker.Release();
    }
 
    //проверка
    for (var i = 1; i < count; i++)
    {
        if (result[i] == 0 || result[i] <= result[i - 1])
        {
            Console.WriteLine($"wrong {i} = {result[i]}");
        }
    }
});
 
Task.WaitAll(t1, t2);
Console.WriteLine("Completed!");
Console.ReadKey();

Цитата Сообщение от prajdziswet Посмотреть сообщение
тут неименованые светафоры и пример, только для своего потока
замените на именованые -- результат будет тот же. Как и два разных приложения. Причем можно даже ТАК

Пишущее приложение
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
var readLocker = new Semaphore(0, 1, "nya-read-lock");
var writeLocker = new Semaphore(1, 1, "nya-write-lock");
 
var count = 100;
 
for (var i = 0; i < count; i++)
{
    writeLocker.WaitOne();
    File.WriteAllBytes(@"D:\Temp\buff.txt", BitConverter.GetBytes(i));
    readLocker.Release();
}
Console.WriteLine("Write completed!");
Console.ReadKey();
Читающее приложение
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var readLocker = new Semaphore(0, 1, "nya-read-lock");
var writeLocker = new Semaphore(1, 1, "nya-write-lock");
 
var count = 100;
var result = new int[count];
 
for (var i = 0; i < count; i++)
{
    readLocker.WaitOne();
    result[i] = BitConverter.ToInt32(File.ReadAllBytes(@"D:\Temp\buff.txt"));
    writeLocker.Release();
}
 
//проверка
for (var i = 1; i < count; i++)
{
    if (result[i] == 0 || result[i] <= result[i - 1])
    {
        Console.WriteLine($"wrong {i} = {result[i]}");
    }
}
 
Console.WriteLine("Read completed!");
Console.ReadKey();
Внезапно все работает, хотя это физически два разных процесса. Более того: можно сначала запустить одно любое приложение, подождать сколько влезет, запустить второе и убедится что все отработает как надо.
Вложения
Тип файла: zip CheckLock.zip (2.5 Кб, 4 просмотров)
0
1 / 1 / 0
Регистрация: 02.10.2012
Сообщений: 110
14.04.2023, 08:33  [ТС]
Цитата Сообщение от Неко с ушами Посмотреть сообщение
Ппцц... окей, вот так может яснее будет?
...

замените на именованые -- результат будет тот же. Как и два разных приложения. Причем можно даже ТАК
...
Внезапно все работает, хотя это физически два разных процесса. Более того: можно сначала запустить одно любое приложение, подождать сколько влезет, запустить второе и убедится что все отработает как надо.
- неименованные нерасматриваю, скорее всего для разных приложений они свои. указваю на твои ошибки
1) ты по умолчанию блокируешь семафор
C#
1
var readLocker = new Semaphore(0, 1);
чтения, извеняюсь с какого перепуга?
Файл на диске существует, я его хочу считать, тебе семафор не даст его прочитать, если заменить на 1,1 получишь другой результат. А если 0,1 ты его не считаешь пока не запишешь.


2)
а) в данном случае можно было заменить на один мьютекс, а не два семафора
б) sleep не люишь заменил имитацию долгой работы на чтение клавиши =))
Вот код чтения (модернезированные твои файлы):
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var MutexLocker = new Mutex(false, "nya-lock");
 
var count = 1000;
var result = new int[count];
 
MutexLocker.WaitOne();
Console.WriteLine("вошли в семафор чтения, для продолжение нажмите ввод");
Console.ReadKey();
for (var i = 0; i < count; i++)
{
    result[i] = BitConverter.ToInt32(File.ReadAllBytes(@"D:\buff.txt"));
 
}
MutexLocker.ReleaseMutex();
 
//проверка
for (var i = 1; i < count; i++)
{
    if (result[i] == 0 || result[i] <= result[i - 1])
    {
        Console.WriteLine($"wrong {i} = {result[i]}");
    }
}
 
Console.WriteLine("Read completed!");
Console.ReadKey();
записи:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var MutexLocker = new Mutex(false, "nya-lock");
 
var count = 1000;
MutexLocker.WaitOne();
Console.WriteLine("вошли в семафор записи, для продолжение нажмите ввод");
Console.ReadKey();
for (var i = 0; i < count; i++)
{
   
    File.WriteAllBytes(@"D:\buff.txt", BitConverter.GetBytes(i));
  
}
MutexLocker.ReleaseMutex();
Console.WriteLine("Write completed!");
Console.ReadKey();
Nya.CheckLock.zip

все прекрасно работает, причем ты файл можешь считать, не запуская запись и наоборот! (на момент записи/чтение поток блокируется)
0
1 / 1 / 0
Регистрация: 02.10.2012
Сообщений: 110
14.04.2023, 08:34  [ТС]

запустили чтение вошел, запись пока недоступна...и наоборот тож прекрасно работает

п.с по хорошему мин еще добавить проверку сущ. файла, но это не важно
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
14.04.2023, 21:12
Цитата Сообщение от prajdziswet Посмотреть сообщение
чтения, извеняюсь с какого перепуга?
А что вы собираетесь считать, если ещё ничего не записано?

Цитата Сообщение от prajdziswet Посмотреть сообщение
все прекрасно работает
Вы точно проверяли работу своего приложения?

Скачаный ваш пример при запуски приложений (в солюшене для обоих проэктов выставлен Start) выдает вот это, после нажания enter в Read приложении.



Окей, запускаем сначала Write приложение, нажимаем enter, потом запускам Read.... и получаем что читалось только последнее запсаное значение... Разбирать ваш пример нет смысла, он даже в теории не рабочий. У меня пропало желание донести до вас мысль что вы не разобрались синхронизации работы через Mutex и нет понимания "что где и как происходит". Могу пожелать удачи в кодинге, но не удивляйтесь если результат будет печальным.
0
1 / 1 / 0
Регистрация: 02.10.2012
Сообщений: 110
15.04.2023, 08:08  [ТС]
Цитата Сообщение от Неко с ушами Посмотреть сообщение
А что вы собираетесь считать, если ещё ничего не записано?


Вы точно проверяли работу своего приложения?

Скачаный ваш пример при запуски приложений (в солюшене для обоих проэктов выставлен Start) выдает вот это, после нажания enter в Read приложении.

Вложение 1414177

Окей, запускаем сначала Write приложение, нажимаем enter, потом запускам Read.... и получаем что читалось только последнее запсаное значение... Разбирать ваш пример нет смысла, он даже в теории не рабочий. У меня пропало желание донести до вас мысль что вы не разобрались синхронизации работы через Mutex и нет понимания "что где и как происходит". Могу пожелать удачи в кодинге, но не удивляйтесь если результат будет печальным.

Точно проверял, посмотри у меня адрес файла другой.
Причем у тебя точно такая ошибка была, я запустил запись файла небыло ругалось на отсутсвие файла создал просто файла и изменил путь - тогда твое приложение пошло, потом начал изменять.

п.с конечно проверил, я скрин кидал (правда когда оно не прочитало)


п.с2
1) как и чуть выше написал у меня точно такае ошибка была на твоем приложении, при записи (т.к файл не существовал, поэтому я писал еще раньше, что стоило добавить проверку сущ.файла)
2) посмотри путь у тебя он лежал просто в папке Temp
0
1 / 1 / 0
Регистрация: 02.10.2012
Сообщений: 110
15.04.2023, 08:20  [ТС]
Цитата Сообщение от Неко с ушами Посмотреть сообщение
Окей, запускаем сначала Write приложение, нажимаем enter, потом запускам Read.... и получаем что читалось только последнее запсаное значение... Разбирать ваш пример нет смысла, он даже в теории не рабочий. У меня пропало желание донести до вас мысль что вы не разобрались синхронизации работы через Mutex и нет понимания "что где и как происходит". Могу пожелать удачи в кодинге, но не удивляйтесь если результат будет печальным.
= я все понял, просто писал, что у тебя есть баги, вдруг файл существует и я его сначала захочу прочитать - у тебя не выйдет, он будет заблокирован.

А ПРИМЕР РАБОЧИЙ!!!

п.с и если просто создать у тебя там записано 1000байт (т.е файл должен быть как в твем примере, если он у тебя есть добавь путь к Temp. (у нас чуть отличается путь, у меня он в корне, у тебя в темпе)
п.с2 у меня правда и другая ошибка была: поехал домой(на родину) он не запускался писал нету 7Net,хотя вижуал показвал что он установлен. вторая как и писал файла небыло, даже твоя запись у меня ругалось...
0
1 / 1 / 0
Регистрация: 02.10.2012
Сообщений: 110
15.04.2023, 08:26  [ТС]

-твой пример (код виден),
запись, ошибка таже - существоания файла!
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
15.04.2023, 15:21
Мда... хоть видео скидывай, раз настолько все запущенно. Хотя после того как вы уперлись в ошибку "Could not find a part of the path", складываетеся что вы как из анекдота: "я не читатель, я писатель!" Пожалуй откланяюсь, потмоу как если на первых ваших скринах вывода "работающего примера" не хватало "Read completed!" и "Write completed!" и это можно было объяснить невнимательностью... то после вывода простыни из wrong и уверености что "все ок" -- не, ну это уже как минимум А+, а у меня только белый пояс.
0
403 / 265 / 69
Регистрация: 12.04.2020
Сообщений: 1,404
15.04.2023, 16:22
Цитата Сообщение от prajdziswet Посмотреть сообщение
запись, ошибка таже - существоания файла!
а файл есть?
0
1 / 1 / 0
Регистрация: 02.10.2012
Сообщений: 110
15.04.2023, 19:40  [ТС]
Цитата Сообщение от Неко с ушами Посмотреть сообщение
Мда... хоть видео скидывай, раз настолько все запущенно. Хотя после того как вы уперлись в ошибку "Could not find a part of the path", складываетеся что вы как из анекдота: "я не читатель, я писатель!" Пожалуй откланяюсь, потмоу как если на первых ваших скринах вывода "работающего примера" не хватало "Read completed!" и "Write completed!" и это можно было объяснить невнимательностью... то после вывода простыни из wrong и уверености что "все ок" -- не, ну это уже как минимум А+, а у меня только белый пояс.
без коментариев, если человек сам скидвает неработающий пример, а в похожей ошибки не может исправить в одной строчке кода...(я думал человек сразу увидит, что я изменил путь)

1- мой модернезированный, 2-твой иходный //ошибка таже, причем при записи, файл по идеи не существует, но не тут было
(у тебя добавляется ошибка директории, у мастера с белым поясам, директорию не проверям, что существует)
NO COMMENT!!!
0
1 / 1 / 0
Регистрация: 02.10.2012
Сообщений: 110
15.04.2023, 19:40  [ТС]
Цитата Сообщение от Dr9vik Посмотреть сообщение
а файл есть?
buff.txt -файл образуется если просто запустить сначала запись (незнаю как неко запускал
(у него нет проверки директории, а у меня существования файла, поэтому ошибки //но они примерно одинаковые
0
1 / 1 / 0
Регистрация: 02.10.2012
Сообщений: 110
15.04.2023, 19:50  [ТС]
мой пример он просто запустил чтение и мьютекс заблокировал запись, поэтому у него запись не работала, а в чтении вывалилась ошибка.

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

а насчет сброса разделяемой памяти я так не понял, пересобрал решение, нормально читало//хотя очень редко скидвала (поставил запись в форме, что она открыта)
______
ладно забыли и проехали все работает, и мой и его пример правда проверки стоило добавить - это так к слову
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
15.04.2023, 19:50

Разделяемая память
Добрый день. Скажите, если в разделяемую память поместить файл, через какое время он затрётся, и обратиться к нему будет невозможно? Что...

Разделяемая память между двумя процессами
Стоит задача в том, чтобы сделать разделяемую память для двух процессов, в котором один процесс записывает данный (пускай какие-то...

Управление процессами, передача данных между процессами
Постановка задачи 1. Осуществить обмен текстовыми и графическими данными между двумя приложениямиP1 и P2 с выводом информации в заданную...

Передача сообщений между процессами
Python 3.4. GUI - WxPython Имеется локальный сервер на Flask. На сервере крутится страничка, которая каждую секунду опрашивает БД....

Передача handle между процессами
Есть 1й процесс который создает файл и записывает в него информацию из Edit, после чего создает 2й поток и в качестве параметра передает...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
36
Ответ Создать тему
Новые блоги и статьи
Расчёт периметра прямоугольника по координатам вершин
Maks 18.07.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Вычислить периметр прямоугольника, заданного координатами своих вершин на плоскости. Решение: Создан документ со следующими. . .
Подсчёт частоты трёхбуквенных слов в тексте
Maks 18.07.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Выясните, сколько раз в предложенном тексте встречается каждое трехбуквенное слово. Решение: Создан документ с единственным. . .
Сумма и количество положительных элементов в чётных строках массива
Maks 18.07.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Вычислить сумму и количество положительных элементов массива, расположенных в четных строках. Решение: Создан документ с. . .
Поиск произведения положительных чётных чисел в последовательности
Maks 18.07.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Дана произвольная последовательность целых чисел. Найти произведение положительных четных чисел данной последовательности. . . .
Обработка трёх чисел: утроение и возведение в степень
Maks 18.07.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Даны три действительных числа. Утроить те из них, значения которых неотрицательны, и возвести в четвертую степень отрицательные. . . .
Расчёт стоимости яблок по весу
Maks 18.07.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Написать программу вычисления стоимости некоторого количества (по весу) яблок. Решение: Создан документ, с табличной частью. . .
сукцессия 30. Фосфорный и азотный замки по "честному" закону лимитирования Либиха
anaschu 16.07.2026
Основные достижения за последние дни 1. Механизм отложенного высвобождения фосфора Добавлен специальный пул для медленного разложения меланизированных гиф ЕСМ Реализована разная скорость. . .
Запрет пометки на удаление и отмены проведения
Maks 16.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "ПутевойЛист" разработанного в КА2. Задача: запретить помечать на удаление и отменять проведения путевого листа при условии, если он сдан. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru