Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
11 / 11 / 7
Регистрация: 23.12.2015
Сообщений: 950

Не выполнять метод и не создавать объект, пока предыдущий вызов не закончит работу

10.08.2018, 01:40. Показов 1833. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет! Я пишу многопользовательское приложение, в котором люди оставляют заказы и они регистрируются в системе. Для оформления заказа я создаю объект и вызываю метод:
C#
1
2
Order order = new Order();
CreateOrder(client);
Так вышло, что для создания заказа система должна каждый раз авторизоваться, добавлять заказ и дальше происходит LogOut.
Да, знаю, что это не совсем правильно, а, вернее, совсем неправильно, но это вынужденная, хоть и временная мера. Благо, системой этой будет пользоваться не очень много людей и не очень интенсивно.
Так вот, подскажите, как исключить конфликты, когда два человека примерно в одно время оформляют заказ? То есть не создавать объект и не выполнять метод и хранить информацию о следующем заказе, пока не выполнится метод LogOut()?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
10.08.2018, 01:40
Ответы с готовыми решениями:

когда алгоритм закончит свою работу?
Подскажите пожалуйста при каких значениях алгоритм закончит свою работу ? 1) А=-2, С=-3 2) А=-3, С=-3 3) А=-3, С=-2 4) А=-3,...

Отправить нажатие клавиш в неактивное окно и определить, когда стороннее приложение закончит работу
открывается приложение X Dim dp As New Process() dp.StartInfo.FileName = "c:\X.exe" ...

Выполнять действия, пока х не равно 25
Подскажите, допустим у меня есть переменная х, как выполнить над ней операции, чтобы она изменялась только в подпрограммах. Например: ...

14
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
10.08.2018, 01:54
Скинь код, в котором ты имитируешь проблему. То есть, если это, например, консольное приложение (сервер), то скинь его (не всю реализацию, можно даже с пустыми методами, просто макет рабочий). Например, я посмотрю и увижу метод, из кода которого будет понятно, что если этот метод вызовут одновременно (или почти), то будет ошибка. Вот так будет тебе помочь значительно легче.

Добавлено через 2 минуты
Я представляю это так: в CreateOrder вызывается операция авторизации по конкретному пользователю, создаётся заказ и потом вызывается тот самый LogOut. Авторизованным может быть только один пользователь в один момент времени. Тебе нужно, чтобы если пришло несколько запросов от разных людей, то все эти несколько заказов создались и система не легла. Верно?

Добавлено через 25 секунд
Если я всё верно понял, то код не нужен.

Добавлено через 17 секунд
Но нужен твой ответ.

Добавлено через 4 минуты
Первое, что пришло на ум - создать потокобезопасную очередь и обрабатывать сообщения по очереди (она может пополняться одновременно из неё браться данные на обработку).
1
11 / 11 / 7
Регистрация: 23.12.2015
Сообщений: 950
10.08.2018, 02:19  [ТС]
Casper-SC, увы, авторизация вызывается не по конкретному пользователю, а для одного единственного - администратора. Именно он отправляет данные в систему. То есть администратор авторизовался, добавил заказ и вышел.
Если нужен код, то я отправлю его утром.
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
10.08.2018, 04:24
Лучший ответ Сообщение было отмечено DenKG как решение

Решение

Говоря про очередь, я имел ввиду что-то вроде такого:
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
 
namespace ConsoleApp1
{
    class Program
    {
        #region Entry point
 
        static Program _program;
 
        static void Main(string[] args)
        {
            _program = new Program();
            _program.Run(args);
        }
 
        #endregion
 
        private Random _random1;
        private Random _random2;
 
        private ConcurrentQueue<string> _orderQueue;
        private AutoResetEvent _orderAddedEvent;
        private CancellationTokenSource _cancellationTokenSource;
 
        private void Run(string[] args)
        {
            _random1 = new Random();
            _random2 = new Random();
 
            _orderQueue = new ConcurrentQueue<string>();
            _orderAddedEvent = new AutoResetEvent(false);
            _cancellationTokenSource = new CancellationTokenSource();
 
            FillQueueAsync().LogErrors();    // Ожидать завершения не нужно. Идём дальше.
            ProcessQueueAsync().LogErrors(); // Ожидать завершения не нужно. Идём дальше.
 
            Console.ReadKey();
 
            _cancellationTokenSource.Cancel();
 
            _cancellationTokenSource.Dispose();
            _orderAddedEvent.Set();
            _orderAddedEvent.Dispose();
        }
 
        private async Task ProcessQueueAsync()
        {
            await Task.Factory.StartNew(async () =>
            {
                while (!_cancellationTokenSource.IsCancellationRequested)
                {
                    string order = null;
 
                    while (!_cancellationTokenSource.IsCancellationRequested && _orderQueue.Count > 0 && !_orderQueue.TryDequeue(out order)) { }
 
                    if (order != null)
                    {
                        await CreateOrderAsync(order);
                    }
 
                    _orderAddedEvent.WaitOne();
                }
            });
        }
 
        private async Task CreateOrderAsync(string order)
        {
            await Task.Delay(_random1.Next(125, 750), _cancellationTokenSource.Token);
            Console.WriteLine($"Заказ \"{order}\" обработан.");
        }
 
        private async Task FillQueueAsync()
        {
            await Task.Factory.StartNew(async () =>
            {
                for (int i = 0; i < 20; i++)
                {
                    await Task.Delay(_random2.Next(250, 850), _cancellationTokenSource.Token);
                    _orderQueue.Enqueue($"#{(i + 1).ToString()}");
 
                    _orderAddedEvent.Set();
                }
            });
        }
    }
 
    public static class TaskExtensions
    {
        public static async void LogErrors(this Task task)
        {
            try
            {
                await task;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Exception {ex.ToString()}");
            }
        }
    }
}
1
11 / 11 / 7
Регистрация: 23.12.2015
Сообщений: 950
10.08.2018, 12:31  [ТС]
Casper-SC, вот мой код.
Тут мы создаем объект и вызываем метод для добавления заказа:
C#
1
2
CRMWorker cRMWorker = new CRMWorker();
cRMWorker.InsertOperation(order, Client, addNewContact); //В CRM
В InsertOperation() сначала происходит авторизация администратора, а затем добавление заказа:
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
public async void InsertOperation(Order order, Client client, bool result)
{
        //Авторизация администратора
        await Challenge();
 
        //Дальше тут куча проверок на наличие заказчика
        //И потом уже оформляется заказ
            var CRMorder = new CRMOrder()
            {
                subject = $"Заказ из чатбота | {client.Name} {client.LastName}",
                account_id = $"{account_id}", 
                contact_id = $"{contact_id}",
                sostatus = "Создано",
                assigned_user_id = "0x0",
                ship_street = $"{ order.Address }",
                invoicestatus = "Автосоздан",
                productid = "0x0",
                LineItems = new List<Item>
                          {
                             new Item
                             {
                                productid = "0x0",
                                listprice = "150", //Цена за единицу
                                quantity = $"{ order.CountBottle }"
                             }
 
                          }
            };
 
            string jsonData1 = JsonConvert.SerializeObject(CRMorder);
 
            var responseString = await "https://site.net/webservice.php"
            .PostUrlEncodedAsync(new { operation = "create", sessionName = sessionID, elementType = "Table", element = jsonData1})
            .ReceiveString();
 
            //Выход администратора из системы
            await LogOut();
0
 Аватар для zewer
2357 / 1775 / 212
Регистрация: 07.01.2011
Сообщений: 10,342
10.08.2018, 21:10
Не очень понимаю, как конкретно выглядит система, но разве тут нельзя использовать паттерн Singleton?
Началась сессия - в объекте что-то есть. После окончания сессии - на обьект вкидывайте null
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
10.08.2018, 21:35
zewer, по-моему я автору уже дал ответ (в смысле я не пойму, почему автор думает, что тот ответ не подошёл).

Если у нас никак нельзя сделать с текущим кодом, кроме как выполнять по очереди, то делаем очередь и сохраняем заказы по очереди.

Добавлено через 1 минуту
И про синглтон вообще не понял, как он тут поможет.

Добавлено через 1 минуту
Вероятно, имеется ввиду, что есть экземпляр класса, который содержит в себе очередь и он синглтон? Или что? Автору, судя по всему, нужна возможность подключиться нескольким админам и чтобы их заказы были сохранены.
0
 Аватар для zewer
2357 / 1775 / 212
Регистрация: 07.01.2011
Сообщений: 10,342
10.08.2018, 21:48
Цитата Сообщение от Casper-SC Посмотреть сообщение
Вероятно, имеется ввиду, что есть экземпляр класса, который содержит в себе очередь и он синглтон? Или что?
На уровне сервера сделать проверку, используется ли обьект класса в текущий момент
Если да - ждать/поместить в очередь/что-то инное, потому что не очень понимаю как выглядит система
П.С. Система то клиент-сервер-БД ?
0
11 / 11 / 7
Регистрация: 23.12.2015
Сообщений: 950
10.08.2018, 23:08  [ТС]
Casper-SC, нет, я с вами согласен. Всё хорошо) Просто на всякий случай привёл код. Вдруг у вас бы появились еще идеи

P.S.:И такой вопросик, не совсем относящийся к теме. А вот этот метод public async void InsertOperation(Order order, Client client, bool result) может вернуть булево значение?

Добавлено через 3 минуты
Цитата Сообщение от zewer Посмотреть сообщение
П.С. Система то клиент-сервер-БД ?
Да, именно так
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
10.08.2018, 23:12
Цитата Сообщение от DenKG Посмотреть сообщение
А вот этот метод public async void InsertOperation(Order order, Client client, bool result) может вернуть булево значение?
Если только так:
C#
1
2
3
4
5
        private async Task<bool> CreateOrderAsync(string order)
        {
            await Task.Delay(_random1.Next(125, 750), _cancellationTokenSource.Token);
            return true;
        }
0
11 / 11 / 7
Регистрация: 23.12.2015
Сообщений: 950
10.08.2018, 23:14  [ТС]
Цитата Сообщение от Casper-SC Посмотреть сообщение
await Task.Delay(_random1.Next(125, 750), _cancellationTokenSource.Token);
А что эта строка делает?
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
10.08.2018, 23:19
Последний метод, который вызывает всю цепочку асинхронных методов, тот который async void должен во-первых ожидать результат через await, во вторых этот вызов должен быть помещён в try catch и логироваться исключение.

Добавлено через 2 минуты
Цитата Сообщение от DenKG Посмотреть сообщение
А что эта строка делает?
Это просто метод из кода, который я приводил выше. Конкретно тут await Task.Delay это аналог Thread.Sleep, но не вешает вызывающий поток. Да не обращай внимание на Task.Delay, ты просил возврат значения из асинхронного метода, я показал.

Добавлено через 55 секунд
Начало сообщения про это:
C#
1
2
3
4
5
6
7
8
9
10
11
        public static async void LogErrors()
        {
            try
            {
                bool result = await CreateOrderAsync("");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Exception {ex.ToString()}");
            }
        }
Добавлено через 1 минуту
Пустая переданная строка в метод ничего не значит. Это просто чтобы компилилось
Вывод инфы в Console.WriteLine это не логирование, это просто мне лень писать боевое логирование
1
11 / 11 / 7
Регистрация: 23.12.2015
Сообщений: 950
10.08.2018, 23:19  [ТС]
Casper-SC, спасибо большое
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
10.08.2018, 23:19
DenKG, пожалуйста. В итоге получилось решить проблему (имею ввиду, по факту в проекте)?
0
11 / 11 / 7
Регистрация: 23.12.2015
Сообщений: 950
11.08.2018, 00:03  [ТС]
Casper-SC, логгер у меня есть в консоль и в файл )
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
11.08.2018, 00:03
Помогаю со студенческими работами здесь

Выполнять пока не прошло n секунд
while (true || .?.) { ...break;... } Подскажите как выполнять по true или пока не прошло n секунд? Если прошло допустим...

Выполнять операции, пока зажата клавиша
Извините за много текста!) Здравствуйте дорогие форумчане! Давно вас читаю, пользуюсь форумом, много раз меня спасали но все не...

Выполнять действие, пока открыта форма
Работаю в Windows Forms. Требуется следующее: Пока форма открыта, то программа что-то делает. Вопрос. Как это реализовать? Желательно с...

Не выполнять действие, пока открыта форма
Здравствуйте. Помогите, пожалуйста, решить небольшую, надеюсь, проблему. Есть форма с кнопкой, при нажатии на которую выполняется...

Выполнять цикл, пока не возникнет ошибка
Доброго времени суток, как правильно обработать выход из цикла по возникновению исключения? Суть такова есть объект, реализация...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru