Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

​Немножко вне рутины...

701  1 2 3 4 все
Murr патриот19.05.17 14:30
Murr
19.05.17 14:30 

Немножко вне рутины...

</p><blockquote style="">
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace A
{
    class A
    {
        StreamWriter sw = null;
        public StreamWriter Sw
        {
            get {
                if(sw == null)
                {
                    // get from class where instantiated/specified.
                }
                return sw;
            }
            set { sw = value; }
        }
    }


    class B1 : A
    {
        String b1 = "B1";
        public void GetResult()
        {            
            Sw.Write(b1);


            B2 b2 = new B2();
            b2.GetResult();
        }
    }


    class B2 : A
    {
        String b2 = "B2";
        public void GetResult()
        {
            Sw.Write(b2);
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            using (StreamWriter sw = new StreamWriter("Data.dat"))
            { 
                B1 b1 = new B1();
                b1.Sw = sw;
                b1.GetResult();
            }
        }
    }
}

</blockquote><p>

Что имеем? Имеем один базовый класс А и несчетное множество производных B*.

Существенно - классы B* между собой НЕ взаимодействуют - нет пересылки данных или передачи параметров, но один класс может инстанцировать другой и вызывать методы другого.


Классы B* выполняют какие-то действия (какие - не суть важно) и помещают результат в stream. Вид stream'а и что именно туда скидывается меня не интересует.


Меня интересует - можно ли в приведенном коде обеспечить чтобы B1 & B2 использовали один и тот же stream?

Чтобы было не слишком легко - несколько Б*шек будут работать параллельно - одним стреамом обойтись не получится - мне нужен именно доступ к тому где он задаn...


#1 
NightWatch коренной житель19.05.17 14:48
NightWatch
NEW 19.05.17 14:48 
в ответ Murr 19.05.17 14:30
можно ли в приведенном коде обеспечить чтобы B1 & B2 использовали один и тот же stream?

Ответ, по-моему, очевиден: нет.

#2 
Программист коренной житель19.05.17 15:05
NEW 19.05.17 15:05 
в ответ Murr 19.05.17 14:30
Существенно - классы B* между собой НЕ взаимодействуют - нет пересылки данных или передачи параметров, но один класс может инстанцировать другой и вызывать методы другого.

Что-то я не понял, если классы B* между собой не взаимодействуют, то как один класс может инстанциировать другой и вызывать его методы?


Меня интересует - можно ли в приведенном коде обеспечить чтобы B1 & B2 использовали один и тот же stream?
Чтобы было не слишком легко - несколько Б*шек будут работать параллельно - одним стреамом обойтись не получится - мне нужен именно доступ к тому где он задаn...

Делаешь фабрику стримов и пусть она принимает решение о том, создать новый стрим или вернуть один из существующих.

#3 
Murr патриот19.05.17 16:03
Murr
NEW 19.05.17 16:03 
в ответ NightWatch 19.05.17 14:48

Ответ, по-моему, очевиден: нет.

-----

Хммм... Я бы не был столь категоричен.

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


Одним из вариантов решения будет сделать поток статическим. Но этот вариант меня не устраивает,

т.к. пора перебираться из однопоточной задачи в многопоточную.

Надо придумать что-то типа треад-статик вариабле... Что на 100% возможно.


Но там получается другая (см. внизу) сложность.


Изначально это делается чтобы сократить издержки на создание стреамов. Они - неприемлемо высокие.

Первоначально Я сделал пулл потоков и подставлял стреам из пула когда его запрашивали.

Относительно начальной схемы, где стреамы создавалось локально, все существенно ускорилось.

Пулл был рамером в 120 стреамов. Больше 240 - не выдерживала ОСь. Возможно, что можно что-то

подстроить (см Филес в конфиге), но проблема не в этом - там была однозадачная система. А мне сейчас

нужно иметь параллельность выполнения. При параллельном выполнении количество задействованных

стреамов очень быстро достигнет предела. Каким бы предел ни был. Т.е. это не вариант.


Так что остается только контролировать количество исполняемых треадов и гарантировать что

в треаде используется один стреам. И этот стреам надо как-то шарить между Бешками.


А упомянутая выше сложность заключается в том, что треад не умеет (ну или Я не умею) возвратить

стреам в пулл по завершении потока. А создавать его каждый раз внутри потока - накладно...


#4 
Murr патриот19.05.17 16:25
Murr
NEW 19.05.17 16:25 
в ответ Программист 19.05.17 15:05

если ... то

-----

Ну давай напишем - ограниченно взаимодействуют - могут вызвать единственный хорошо известный метод без параметров.

Ничего добавить Я не могу - Бешки - не рукотворные и имеют жесткие ограничения.

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

Чтобы было совсем весело - подозреваю, что мне еще и инстансы Бешек надо будет кешировать... смущ


Делаешь фабрику стримов

-----

У меня есть пулл стреамов.

Потому что создавать их дорого.

Но пулл, к сожалению, не может принимать подобные решения.

Можно написать менеджера.

Примерно так, как сделано в Main - b1.Sw = sw; - но это - внешнее управление.

Мне нужно, чтобы эту задачу решал код в инстансе А, который "НЕ знает" кто пытается получить доступ к стреаму, но "знает", при отсутствии стреама инстанциация производится где-то внутри метода другой Бешки у которой есть нужный стреам. Вот до него мне и надо добраться.


Как-то так.

#5 
NightWatch коренной житель19.05.17 18:19
NightWatch
NEW 19.05.17 18:19 
в ответ Murr 19.05.17 16:03, Последний раз изменено 19.05.17 18:24 (NightWatch)
Существенно - классы B* между собой НЕ взаимодействуют - нет пересылки данных или передачи параметров,

Говорит о том, что реализация классов тебе не доступна, иначе почему бы GetResult не изменить так, чтобы он принимал в качестве аргумента поток, или передать его через конструктор.

А

public StreamWriter Sw
{
    get {
        if (sw == null) {
          // get from class where instantiated/specified.
        }
        return sw;
    }
    set {
        sw = value;
    }
}

исключает контроль над используемым потоком: неизвестно как и откуда getter берет поток, а setter вообще позволяет вызывающему коду подсунуть свой.

#6 
Murr патриот19.05.17 19:48
Murr
NEW 19.05.17 19:48 
в ответ NightWatch 19.05.17 18:19

реализация классов тебе не доступна

-----

Доступна, но изменять ее Я хоть и не не могу, но очень сильно не хочу.

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


почему бы GetResult не изменить так, чтобы он принимал в качестве аргумента поток, или передать его через конструктор.

-----

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

А во вторых - надо будет каждый раз помнить об параметре... в том месте где Я пытаюсь освободится от какой-либо передачи параметров.


неизвестно как и откуда getter берет поток

-----

КАК - неизвестно - это и есть мой вопрос, а ОТКУДА - вполне известно - это тот же поток, который передан Б1 и лежит в его инстансе. Вопрос - как добраться до этого инстанса в указанных ограничениях?


В принципе... вроде должно получится так - добавить в базовый класс еще один метод и при вызове этого метода... нее, опять не пойдет... Ладушки - сегодня думать уже нечем - пора отдыхать...

#7 
  moose свой человек19.05.17 23:23
NEW 19.05.17 23:23 
в ответ Murr 19.05.17 14:30, Последний раз изменено 19.05.17 23:25 (moose)

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

Но не лучше ли было бы без никакого описания Вашего "дизайна", который Вы не можете заставить работать, описать просто и понятно Вашу изначальную проблему? Думаю, если Вам удастся ее четко сформулировать, то и решение Вы сами увидите тотчас. Или кто-то из публики его сможет Вам подсказать.

Вам нужно создать thread safe stream, или что-то еще?

#8 
AlexNek патриот20.05.17 14:03
AlexNek
NEW 20.05.17 14:03 
в ответ Murr 19.05.17 19:48
надо будет каждый раз помнить об параметре

Без изменения архитектуры будешь только заниматься изготовлением костылей. Очень нехорошо передавать поток через проперть.

Даже имена и то странные - void метод начинается с "Гет".


А пока следующее предложение.

Делаем "потоковый записыватель" с очередью заданий. Туда поступают "Бэшки" в требуемом порядке записи (накидал и "забыл"). Затем Бэшки выбираеются из очереди и передаеются врапперу записи, который может залочить поток и записать Бэшку в поток. И так повторяется пока все Бэшки в очереди не закончатся.

Ну а как паралелить записыватели - нужно знать задачу.

#9 
Murr патриот22.05.17 11:19
Murr
NEW 22.05.17 11:19 
в ответ AlexNek 20.05.17 14:03

Туда поступают "Бэшки" в требуемом порядке записи

-----

Если бы Я мог перевести все в список - вопрос бы не возникал.

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

Изменить порядок вызовов или сегментации - увы, не дано...


Даже имена и то странные - void метод начинается с "Гет".

-----

Ну писал на коленке, т.е. непосредственно на Германке - мог и ошибит'ся.

#10 
Murr патриот22.05.17 11:25
Murr
NEW 22.05.17 11:25 
в ответ Murr 19.05.17 14:30

Поменял пока так:


using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ThreadStaticTest
{
class A
{
[ThreadStatic]
static StreamWriter sw = null;
public StreamWriter Sw
{
get
{
if (sw == null)
{
// get from class where instantiated/specified.
throw new Exception("Output stream is null or not specified.");
}
return sw;
}
set { sw = value; }
}
}


class B1 : A
{
String b1 = "B1";
public void GetResult()
{
Sw.Write(b1);


B2 b2 = new B2();
b2.GetResult();
}
}


class B2 : A
{
String b2 = "B2";
public void GetResult()
{
Sw.Write(b2);
}
}

class Process
{
static int threads = 1;

public void Execute()
{
Thread newThread = new Thread(new ThreadStart(this.Generate));
newThread.Name = threads.ToString();
newThread.Start();
}

private void Generate()
{
using (StreamWriter sw = new StreamWriter("Data_" + threads.ToString() + ".dat"))
{
B1 b1 = new B1();
b1.Sw = sw;
b1.GetResult();
}
}
}

class Program
{
static void Main(string[] args)
{
Thread.CurrentThread.Name = "Main";

Process p = new Process();
p.Execute();
}
}
}




Вроде работает. По крайней мере по ексептиону пока не вылетает.

Многопоточку - пока не гонял - надо сделать более-мение нормальный "источник" инстансов Б1 и прикрутить пулл для стреамов.


Будут какие замечания/пожелания/советы?

#11 
Murr патриот22.05.17 11:43
Murr
NEW 22.05.17 11:43 
в ответ moose 19.05.17 23:23

Вы всегда странным образом формулируете Вашу проблему.

------

Ну что тут поделать - Я таки ДУМАЮ странным образом. Ну а как думаю - так и формулирую.

Я знаю, что думать так как думаю Я - довольно сложно... но(!), как показывает практика, довольно эффективно.

По крайней мере, когда так думает команда - все получается довольно гладко...


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

-----

Замени "нужно" на "можно" и Я с тобою соглашусь.


Вам нужно создать thread safe stream, или что-то еще?

-----

Мне нужно шарить стреаm между объектами создаваемыми в потоке. Пока - в том же потоке.

Но вполне возможно, что все сильно-сильно ухудшится и мне нужно будет шарить стреам из внешнего, по отношению к потоку выполнения, пула в пределах потока выполнения между объектами создаваемыми в другом/других потоках.

Понимаю, что звучит сложно и неприятно - но, увы, более внятно пока не формулируется.

#12 
AlexNek патриот22.05.17 19:04
AlexNek
NEW 22.05.17 19:04 
в ответ Murr 22.05.17 11:19
Если бы Я мог перевести все в список - вопрос бы не возникал.

Тогда я не понимаю принципа записи. Если каждый пишет когда хочет, то в файле или бардак или множество мелких записей.

#13 
Murr патриот22.05.17 20:57
Murr
NEW 22.05.17 20:57 
в ответ AlexNek 22.05.17 19:04

Если каждый пишет когда хочет, то в файле или бардак или множество мелких записей.

-----

Каждый пишет когда его "очередь" писать.



    class B1 : A
    {
        String b1 = "B1";
        public void GetResult()
        {            
            Sw.Write(b1 + " 1"); // pishem
 
            B2 b2 = new B2();
            b2.GetResult(); // pishem drugoe

            Sw.Write(b1 + " 2"); // snova pishem
        }
    }



Нормально там все пишется. Пока по крайней мере проблем не видел.


Что меня сейчас интересует - как это будет работать в случае когда класс инстанцируется в другом потоке... Жаль - времени потестить нет - снова надо монстром заниматься...

#14 
AlexNek патриот22.05.17 21:16
AlexNek
NEW 22.05.17 21:16 
в ответ Murr 22.05.17 20:57
как это будет работать в случае когда класс инстанцируется в другом потоке

То бишь B2 b2 = new B2(); располагается не в функции GetResult(), а еще где то?


#15 
Murr патриот22.05.17 23:27
Murr
NEW 22.05.17 23:27 
в ответ AlexNek 22.05.17 21:16

а еще где то?

-----

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

Не понимаю какая у него будет треад-статик статик переменная - потока создания или потока выполнения... Надо тестить...

#16 
AlexNek патриот22.05.17 23:39
AlexNek
NEW 22.05.17 23:39 
в ответ Murr 22.05.17 23:27
Угу... в другом потоке.

А как тогда известно "когда готово"? Это то ведь GetResult должна знать.

#17 
Murr патриот22.05.17 23:45
Murr
NEW 22.05.17 23:45 
в ответ AlexNek 22.05.17 23:39

Инстанцирование - там, выполнение - тут.

Вот как завершится GetResult - так и готово.

#18 
AlexNek патриот23.05.17 00:14
AlexNek
NEW 23.05.17 00:14 
в ответ Murr 22.05.17 23:45
B2 b2 = new B2();
b2.GetResult(); // pishem drugoe

то есть обе строки в другом месте и ты туда не хочешь/не можешь передать поток?

#19 
Murr патриот23.05.17 11:08
Murr
NEW 23.05.17 11:08 
в ответ AlexNek 23.05.17 00:14

то есть обе строки в другом месте и ты туда не хочешь/не можешь передать поток?

-----

IB2 b2 = Program.Factory.Create("B2"); // nado napisat'
b2.GetResult(); // pishem drugoe

И Я не хочу передавать туда поток в ручную - слишком много раз это надо делать и это совершенно никак не относится к решаемой этим кодом задаче.

Но Я хочу, чтобы b2.GetResult() получила доступ к стреаму в потоке выполнения и сделала это без дополнительных телодвижений с моей стороны.

Желательно - и без больших накладных расходов.


У меня вообще есть желание видеть это в одну строку. Примерно так

GetResult("B2");

Возможно, что это и будет решением.


П.С. Как-то оно близко коррелирует с твоими запросами к загрузке плагинов.

#20 
  moose свой человек23.05.17 21:54
NEW 23.05.17 21:54 
в ответ Murr 23.05.17 11:08, Последний раз изменено 23.05.17 21:56 (moose)

Предлагаю переименовать метод getresult() в getSUPERresult(), и все сразу пойдет : )

Это очень важно: назвать метод/переменную так, чтобы ни один шпион не догадался, что там и почему. Назвать класс "Process", и дать ему метод "Execute" (или как там?) - тоже хороший ход, как и назвать использование DLL'ов "плигином". Ребята, извините, но похоже, Вы тут только двое друг друга и понять можете ("неординарно мыслите"). Только зачем форум грузить?

#21 
AlexNek патриот23.05.17 22:39
AlexNek
NEW 23.05.17 22:39 
в ответ moose 23.05.17 21:54
как и назвать использование DLL'ов "плигином"

Можно назвать и "динамически загружаемые объекты", но все же

https://msdn.microsoft.com/en-us/library/ms972962.aspx

Да и название не играет в данном случае большой роли, сама проблема более интересна, хотя да не всем.


Только зачем форум грузить?

Мне кажется коллективная работа всегда интересней индивидуальной, да и в последнее время почти ничего нового и нет.

Неужели задачки не интересно порешать?

#22 
AlexNek патриот23.05.17 22:56
AlexNek
NEW 23.05.17 22:56 
в ответ Murr 23.05.17 11:08
Как-то оно близко коррелирует с твоими запросами к загрузке плагинов.

Особой корреляции не вижу, кроме вопроса со стороны "а нахрена это всё нужно" улыб


и это совершенно никак не относится к решаемой этим кодом задаче.

Код то производит запись в поток, значит как раз то очень и относится.


Можно переписать немного по другому

GetResult("B2"); --> writer.StoreData(typeof(B2));

Где writer не поток а твой класс, а каждая Бэшка реализует интерфейс IStoreData

#23 
Murr патриот24.05.17 10:12
Murr
NEW 24.05.17 10:12 
в ответ moose 23.05.17 21:54

Только зачем форум грузить?

------

Хммм... А зачем же форум существует? Чтобы в него НЕ писать?

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

Я, кстати, думал, что будет несколько сложнее.

Ну теперь следующий шаг - поженить этот код с бакгроундворкером и разнести Бешки по разным либам.

Разве не интересно - будет оно жить или где-то сломается?


назвать метод/переменную так

------

Есть у меня несколько сильно обфусканных сторонних дллок - там имена методов - _а4(), _а5()...

Да еще и полностью декомпилировать не получается - кусок связанный с идентификацией юсера и машины - сплошная ошибка декомпиляции.

Так что радуйся Процессу и Екзекуте...

#24 
Murr патриот24.05.17 10:21
Murr
NEW 24.05.17 10:21 
в ответ AlexNek 23.05.17 22:39
коллективная работа всегда интересней индивидуальной

-----

Интересней - может быть и нет, но всегда будет продуктивнее - Одна голова хорошо, а 1<<1 - лучше.


Неужели задачки не интересно порешать?

-----

Мне временами кажется, что нынешнему поколению действительно не интересно порешать задачки.

Т.е. работают они как чистые исполнители - объяснили что делать, объяснили как делать - работают.

Чуть только задача выпадает из области полученных разъяснений - тупик... сами - ни-ни... ждут пока

все пояснят... Может оно и правильно...

#25 
  moose свой человек24.05.17 11:20
NEW 24.05.17 11:20 
в ответ AlexNek 23.05.17 22:39
Неужели задачки не интересно порешать?

А где здесь задачки?


#26 
  moose свой человек24.05.17 11:23
NEW 24.05.17 11:23 
в ответ Murr 24.05.17 10:21
Мне временами кажется, что нынешнему поколению действительно не интересно порешать задачки.Т.е. работают они как чистые исполнители - объяснили что делать, объяснили как делать - работают.Чуть только задача выпадает из области полученных разъяснений - тупик... сами - ни-ни... ждут покавсе пояснят... Может оно и правильно...


Эй, ты, "вчерашнее поколение", если я тебе не тыкаю (в этот раз только сделаю исключение), то это не от возраста, а от воспитания. Чтобы мудрость из себя изображать, нужно для этого основания какие-то иметь, у Вас их нет.

#27 
Murr патриот24.05.17 11:29
Murr
NEW 24.05.17 11:29 
в ответ AlexNek 23.05.17 22:56

Код то производит запись в поток, значит как раз то очень и относится.

-----

Код должен породить текст.

Вот тот текст, который порождается, меня интересует и интересует очень и очень сильно.

Именно то, какой текст будет порожден кодом и насколько сложно будет модифицировать

порождаемый код и составляет проблему.

То, как это будет реализовано технически - интересует только с позиции чтобы оно никак не

влияло на решение основной задачи.

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

еще как-то упоминать - это, несомненно, плюс.

Аналогично и по параметрам (тут не использовались) - если они НЕ болтаются под руками

- это тоже плюс.


Можно переписать немного по другому

-----

Можно. И даже - будет работать. Мало того - даже пару раз за последние полгода использовал

именно этот формат - нужно было обойти ошибку в подстановке значения с апострофами в

СКЛ. Но это было две строки на 1-1.5 мбайт шаблонов.


Вот два куска кода, делающие одно и то же:

VB


sql = "SELECT " & _

"TO_CHAR(fc.FC_BARCODE,'000000') ""bcd"", " & _

"fc.FC_BATCH_NO ""batchNo"", " & _

"fc.FC_SEQUENCE_NO ""seqNo"", " & _

"fc.FC_PANE_NO ""paneNo"", " & _

"fc.FC_GLAS_SEQ ""compNo"", " & _

"ps.PS_ORDER_NO ""orderNo"", " & _

"ps.PS_ORDER_POS ""itemNo"" " & _

"" & _

"FROM PRD_SEQ ps, PLAN_PARA pp, DAYBOOK db, FLOW_CTRL fc WHERE " & _

"" & _

"fc.FC_BATCH_NO=ps.PS_BATCH_NO AND " & _

"fc.FC_SEQUENCE_NO=ps.PS_SEQUENCE_NO AND " & _

"" & _

"ps.PS_ORDER_NO=db.DB_ORDER_NO AND " & _

"ps.PS_BATCH_NO BETWEEN db.DB_BATCH_NO_FROM AND db.DB_BATCH_NO_TO AND " & _

"" & _

"db.DB_MODE=pp.PP_NUMBER AND " & _

"DECODE(pp.PP_PURPOSE,3,1,4,1,0)=1 AND " & _

"" & _

"NOT EXISTS (" & _

"SELECT LBS_BCD " & _

"FROM C_LOG_BCD_STOCK WHERE " & _

"LBS_BCD=fc.FC_BARCODE AND " & _

"LBS_BATCH_NO=fc.FC_BATCH_NO AND " & _

"LBS_SEQUENCE_NO=fc.FC_SEQUENCE_NO" & _

") AND " & _

"" & _

"ps.PS_ORDER_NO=" & DRBcdStock.Item("orderNo").ToString & " AND " & _

"ps.PS_ORDER_POS=" & DRBcdStock.Item("itemNo").ToString & " AND " & _

"fc.FC_PANE_NO=" & DRBcdStock.Item("paneNo").ToString & " AND " & _

"fc.FC_GLAS_SEQ=" & DRBcdStock.Item("compNo").ToString & " " & _

"ORDER BY TO_CHAR(fc.FC_BARCODE,'000000')"

шаблон


<#@ template language="C#" inherits="Templates.Sql.TSqlTemplateBase" #>

<#@ assembly name="System.Core" #>

<#@ import namespace="System.Linq" #>

<#@ import namespace="System.Text" #>

<#@ import namespace="System.Collections.Generic" #>

SELECT

TO_CHAR(fc.FC_BARCODE,'000000') "bcd",

fc.FC_BATCH_NO "batchNo",

fc.FC_SEQUENCE_NO "seqNo",

fc.FC_PANE_NO "paneNo",

fc.FC_GLAS_SEQ "compNo",

ps.PS_ORDER_NO "orderNo",

ps.PS_ORDER_POS "itemNo"

FROM PRD_SEQ ps,

PLAN_PARA pp,

DAYBOOK db,

FLOW_CTRL fc

WHERE fc.FC_BATCH_NO = ps.PS_BATCH_NO

AND fc.FC_SEQUENCE_NO = ps.PS_SEQUENCE_NO

AND ps.PS_ORDER_NO = db.DB_ORDER_NO

AND ps.PS_BATCH_NO BETWEEN db.DB_BATCH_NO_FROM AND db.DB_BATCH_NO_TO

AND db.DB_MODE = pp.PP_NUMBER

AND DECODE(pp.PP_PURPOSE,3,1,4,1,0) = 1

AND NOT EXISTS (

SELECT LBS_BCD

FROM C_LOG_BCD_STOCK

WHERE LBS_BCD = fc.FC_BARCODE

AND LBS_BATCH_NO = fc.FC_BATCH_NO

AND LBS_SEQUENCE_NO = fc.FC_SEQUENCE_NO

)

AND ps.PS_ORDER_NO = <#= OrderNo #>

AND ps.PS_ORDER_POS = <#= ItemNo #>

AND fc.FC_PANE_NO = <#= PaneNo #>

AND fc.FC_GLAS_SEQ = <#= CompNo #>

ORDER BY TO_CHAR(fc.FC_BARCODE,'000000')

Какой из них проще?

И нахрена во втором писать каждую строку через writer.StoreData(...)?

Тем более, что это сделает компилятор...

И если мне где-то надо вставить этот текст в другой, то


<#@ template language="C#" inherits="Templates.Sql.TSqlTemplateBase" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#
TAsql asql = new TASql();
#>
WITH A AS ( <#= asql.TransformText() #> )
SELECT * FROM A



решает проблему и добавлять сюда какой-то стреам мне ну никак не хочется. Чем проще - тем лучше. Но работать - должно.

ВБшный код, если нужен, сам нарисуешь.


а каждая Бэшка реализует интерфейс IStoreData

-----

Можно. Нужно только поменять компилятор шаблонов. Или писать это дело руками для каждого класса...

#28 
Murr патриот24.05.17 11:33
Murr
NEW 24.05.17 11:33 
в ответ moose 24.05.17 11:23

если я тебе не тыкаю

-----

Прочитай полиси ФИДО. Потом поговорим об воспитании.

#29 
Murr патриот25.05.17 13:30
Murr
NEW 25.05.17 13:30 
в ответ Murr 22.05.17 11:25

Погонял в многопоточном режиме - все работает... На удивление - работает и работает нормально.

Видимо мелкомягкие сумели где-то спереть приличную реализацию потоков...


Вроде - уже постил, но что-то не вижу... видимо германка глючит...



using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ThreadStaticTest3
{
interface IB
{
void GetResult();
}

class A : IB
{
[ThreadStatic]
static StreamWriter sw = null;
public StreamWriter Sw
{
get
{
if (sw == null)
{
// get from class where instantiated/specified.
throw new Exception("Output stream is null or not specified.");
}
return sw;
}
set { sw = value; }
}

public virtual void GetResult() { }
}


class B1 : A
{
String b1 = "B1";
public override void GetResult()
{
Thread.Sleep(300);

Sw.WriteLine(b1 + " 1");
Thread.Sleep(300);

IB b2 = Program.Factory.Create("B2"); // from different thread
b2.GetResult();

Thread.Sleep(300);

Sw.WriteLine(b1 + " 2");

Thread.Sleep(300);
}
}


class B2 : A
{
String b2 = "B2";
public override void GetResult()
{
Sw.WriteLine(b2);
}
}

class Process
{
static int threads = 0;
static object loker = new object();

int thread;

public Process()
{
lock (loker)
{
++threads;
thread = threads;
}
}

public void Execute()
{
Thread newThread = new Thread(new ThreadStart(this.Generate));
newThread.Name = threads.ToString();
newThread.Start();
}

private void Generate()
{
using (StreamWriter sw = new StreamWriter("Data_" + thread.ToString() + ".dat"))
{
B1 b1 = new B1();
b1.Sw = sw;
b1.GetResult();
}
}
}

class Factory
{
public IB Create(string pName)
{
IB temp = null;
switch(pName)
{
case "B1":
temp = new B1();
break;

case "B2":
temp = new B2();
break;

default:
throw new Exception("Factory can't create item - " + pName);
}
return temp;
}
}

class Program
{
static void Main(string[] args)
{
Thread.CurrentThread.Name = "Main";

Factory = new Factory();

for (int i = 0; i < 20; ++i)
{
Process p = new Process();
p.Execute();
}
}

//private static Factory factory;
//public static Factory Factory { get { return factory; } }
public static Factory Factory { get; private set; }
}
}




Тут вроде все понятно.


Теперь об трудностях.

Есть такая радость - БэкгроундВоркер.

Пользовал Я его уже достаточно много, но пока не требовалось получать доступ к полям объекта после выполнения работы.

Кто-нибудь делал? Мне нужно вернуть стреам из Б1 в пулл по окончании работы.


#30 
AlexNek патриот25.05.17 14:14
AlexNek
NEW 25.05.17 14:14 
в ответ moose 24.05.17 11:20
А где здесь задачки?

К сожалению, я не знаю, что вам интересно и какой примерно тип мышления у вас. Поэтому подобрать стиль ответа непросто.

По моему мнению, задачки где то по "архитектуре ПО", вполне допускаю, что это вас абсолютно не интересует. А задачками будет типа "сделать прогу выводящую свой код".

Может Вы тогда приведёте пример задачи по Вашему?

#31 
AlexNek патриот25.05.17 14:21
AlexNek
NEW 25.05.17 14:21 
в ответ Murr 24.05.17 11:29
Вот два куска кода, делающие одно и то же

Что не видно прямой связи с первоначальной задачей. То бишь понятно что она у тебя в голове осталась.

Но мы то о данной связи никак не догадываемся.


#32 
AlexNek патриот25.05.17 14:29
AlexNek
NEW 25.05.17 14:29 
в ответ Murr 25.05.17 13:30
но пока не требовалось получать доступ к полям объекта после выполнения работы.

Ничего не понял точно. Но если тебе нужно что то получить из завершившего свою работу потока, то кинь ему класс с началом работы, пусть пишет всё что тебе нужно. Оттуда и заберешь. Или еще можно копию данных через евент отослать.

#33 
AlexNek патриот25.05.17 14:40
AlexNek
NEW 25.05.17 14:40 
в ответ Murr 25.05.17 13:30

Кстати, знаешь отчего не следует писать имена классов прямым текстом "B1", а лучше брать этот же текст из типа?

Со временем обязательно кто то захочет переименовать класс и вполне может пропустить текст.

#34 
Murr патриот25.05.17 14:51
Murr
NEW 25.05.17 14:51 
в ответ AlexNek 25.05.17 14:21

Но мы то о данной связи никак не догадываемся.

-----

Ну так и не привязывай это дело к первоначальной задаче.

Оцени независимо какой вариант тебе легче модифицировать. Ну скажем тебе надо временно исключить из набора третье сверхы поле.

#35 
Murr патриот25.05.17 14:58
Murr
NEW 25.05.17 14:58 
в ответ AlexNek 25.05.17 14:29

Или еще можно копию данных через евент отослать.

-----

Угу...

Такой евент уже написан в БэкгроундВоркере.

Только вот у меня получить в нем копию данных не получается...


из завершившего свою работу потока

------

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

Можно получить перед завершением. но 100% - синхронно.

#36 
AlexNek патриот25.05.17 15:01
AlexNek
NEW 25.05.17 15:01 
в ответ Murr 25.05.17 14:51
Ну так и не привязывай это дело к первоначальной задаче.

стоп, стоп. У меня была информация только о задаче 1 и ёё я и пытался решать безо всякого контекста.

Теперь ты предлагаешь задачу 2..

Видмо тебе нужно решить задачу 3, но ты этого еще не можешь объяснить спок

#37 
Murr патриот25.05.17 15:02
Murr
NEW 25.05.17 15:02 
в ответ AlexNek 25.05.17 14:40

лучше брать этот же текст из типа?

-----

Чтоб оно меня здесь волновало... безум


А там где объектов поболе - там вообще нет литеральных констант. Даже там где можно. Закон.

#38 
AlexNek патриот25.05.17 15:09
AlexNek
NEW 25.05.17 15:09 
в ответ Murr 25.05.17 14:58
Можно получить перед завершением

Конечно об этом и речь в случае эвента.

А вот в случае с доп. классом нет. Он живет до начала потока и после него.

#39 
Murr патриот25.05.17 15:20
Murr
NEW 25.05.17 15:20 
в ответ AlexNek 25.05.17 15:01

стоп, стоп. У меня была информация только о задаче 1 и ёё я и пытался решать безо всякого контекста.

Теперь ты предлагаешь задачу 2..

-----

Возьми третью часть того поста - там где один из первых врапится - и реши ее через предлагаемый тобой вариант.

Потом сравни с тем что приведено в третьем блоке кода.

Где будет ПРОЩЕ?

Ну теперь представь, что ЭТО будет ваять... хммм... ну вон хоть Мышонок....

Может там еще упростить? До уровня <# GetResult("B2") #>? Меня ведь интересует только подстановка результата по месту написания с минимальными затратами.


Видмо тебе нужно решить задачу 3, но ты этого еще не можешь объяснить спок

-----

Таки - да, есть следующий фрагмент - уработать выше показанное в компактненькую и флексибилитную подсистемку генерации.

Ну там еще будет 3.а, 3.б, 4.а.б.ц.д.е... 556.а и т.п.

На то она и разработка...смущ

#40 
Murr патриот25.05.17 15:28
Murr
NEW 25.05.17 15:28 
в ответ AlexNek 25.05.17 15:09

Он живет до начала потока и после него.

-----

Если он не отдан потоку.

Я не уверен, что механизм сообщений удержит объект от освобождения. По крайней мере в обычных сообщения винды такой возможности нет.

Еще моментик, который, как мне кажется, ты упускаешь - используется пулл. Пулл не хранит ссылку на объект после его отдачи. Локальная переменная в методе - либо перезатрется, либо освободится с окончанием метода. Остается одна ссылка на объект - та, которая отдана потоку.

Проблема в том что она не доступна в комплитион-евенте.

#41 
AlexNek патриот25.05.17 15:46
AlexNek
NEW 25.05.17 15:46 
в ответ Murr 25.05.17 15:20
Возьми третью часть того поста - там где один из первых врапится.. Потом сравни с тем что приведено в третьем блоке кода

Знаешь что это мне напоминает? "Пойди туду не знаю куда, возьми то не знаю что". То бишь ты то всё удерживаешь, а я не держу все нити в голове.


Ну там еще будет 3.а, 3.б, 4.а.б.ц.д.е... 556.а и т.п.На то она и разработка...смущ

ну не до такой же степени. Все главные требования должны быть известны ДО начала разработки, чтобы выработать правильный "концепт". Всё остальное может идти только в рамках модификации данного концепта. Ну или прийдется концепт менять, если новые хотелки настолько важны.

#42 
AlexNek патриот25.05.17 15:53
AlexNek
NEW 25.05.17 15:53 
в ответ Murr 25.05.17 15:28
Еще моментик, который, как мне кажется, ты упускаешь

Скорее всего не имею представления, что там понаделал.

Никогда еще не возникало проблем с передачей данных из треда. Я передаю туда "Callback" интерфейс и через него получаю все что потребуется.

#43 
Murr патриот25.05.17 16:39
Murr
NEW 25.05.17 16:39 
в ответ AlexNek 25.05.17 15:46

я не держу все нити в голове.

-----

Основная проблема в шаблонах - объем кода и сложность логики генерации.

Любое сокращение рассматриваемого объема кода или упрощение логики генерации - есть дело полезное и оправданное.

Потому код режется на более-менее понятные куски и пихается в разные шаблоны - до уровня понимабельности.

Когда все разобрано - надо собрать порожденный текст в кучку.


Так вот то что обсуждается - каким образом уменьшить затраты на собирание этого текста.

Затраты есть трудовые - количество времени на внесение изменений в существующие шаблоны.

И затраты есть технические - количество задействованных стреамов, памяти и общее время исполнения.


Когда ты, или кто еще, предлагаешь вариант имплементации Я больше всего думаю об том, насколько больше/меньше ручной работы потребуется в случае внесения изменений. Во вторую очередь - как оно отразится на ресурсах системы.


Вот тебе и было предложено оценить трудозатраты в предлагаемом тобою варианте. Т.е. вместо:


<#@ template language="C#" inherits="Templates.Sql.TSqlTemplateBase" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>

WITH A AS ( <# GetResult("B2"); #> )

SELECT * FROM A



написать что-то вида:


<#@ template language="C#" inherits="Templates.Sql.TSqlTemplateBase" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<# writer.StoreData(typeof(B2)) // B2 tut, odnako, nedostupno - est' IB...
#>

WITH A AS ( <# string temp = b2.TransformText(); stream.Write(temp); #> ) <# // tut ne slozhno, no nado pojasnit' kuda budet pisat'sja... #>

SELECT * FROM A <#+ new StreamWriter stream { get { return base.SW; } } // :) #> // что будет на вyходе?

Ну да - глупостей Я там намеренно налепил немеряно... и мог бы добавить и еще...

Но это чисто для индикации того, что код шаблона нужен как можно более простым, с удалением всего что мешает понимать каким будет результат.

#44 
Murr патриот25.05.17 16:42
Murr
NEW 25.05.17 16:42 
в ответ AlexNek 25.05.17 15:53

не имею представления, что там понаделал.

-----

Пулл есть пулл. Имплементирован пулл-паттерн.

#45 
AlexNek патриот25.05.17 17:02
AlexNek
NEW 25.05.17 17:02 
в ответ Murr 25.05.17 16:39
что код шаблона нужен как можно более простым

Что то смутно припоминаю где то должен был проект МуркаТ4, но там дело было в параметрах помнится.

Но и по генерации было море ограничений. И что то с шаблонами мне больше не хочется связываться. Я бы всё равно делал по другому.


Не забывай что в 1м примере был приведен чисто код без упоминания шаблонов.

#46 
Murr патриот25.05.17 19:01
Murr
NEW 25.05.17 19:01 
в ответ AlexNek 25.05.17 17:02

но там дело было в параметрах помнится.

-----

Ну так параметры - это другая задача.

Она рассмотрена в достаточной мере, выработано какое-то решение и лежит ждет имплементации.

Именно по этому сегодняшняя схема вообще не упоминает параметры.


И что то с шаблонами мне больше не хочется связываться.

был приведен чисто код без упоминания шаблонов.

-----

смущ Ты их просто не умеешь готовить.

Собственно, чтобы не смущать всех шаблонами Я их и упростил до объекта с методом.

Грубо, но достаточно точно.



Я бы всё равно делал по другому.

-----

Ну, допустим, ты сделаешь идеальный, по твоему мнению, вариант.

Ну, допустим, Я посмотрю на твой вариант, восхищусь им до невозможности.

Ну, допустим, еще человек 5-10-15 будут в восхищении...


Вопрос - каким чудом можно будет обучить хотя бы 100-200 тыс прогеров пользоваться именно твоим вариантом?

Ну а если не получится - зачем пыхтеть и делать сервис для их загрузки/исполнения? спок

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




#47 
AlexNek патриот25.05.17 21:51
AlexNek
NEW 25.05.17 21:51 
в ответ Murr 25.05.17 19:01
Вопрос - каким чудом можно будет обучить хотя бы 100-200 тыс прогеров пользоваться именно твоим вариантом?

А каким чудом ты это получишь для твоего варианта?

Конечно я буду делать под то насколько знаю твою систему, а это где то возле -273 °C смущ

То бишь прийдется многое воображать как оно может быть.


А так, мне достачно чтобы системой могли пользоваться люди заплатившие за это деньги. И там счёт идет явно не на тысячи.

Чтобы было понятно у не чисто софтверные проекты. Народ покупает железяку, а она без софта так и останется железякой.

#48 
  moose свой человек26.05.17 21:11
NEW 26.05.17 21:11 
в ответ AlexNek 25.05.17 14:14

По моему мнению, задачки где то по "архитектуре ПО", вполне допускаю, что это вас абсолютно не интересует. А задачками будет типа "сделать прогу выводящую свой код".Может Вы тогда приведёте пример задачи по Вашему?

Так Вы решили, что треп в этом топике - это "задачки где-то по архитектуре ПО"? Т.е. Вы - архитектор? Почему тогда уж сразу не Наполеон...


#49 
AlexNek патриот26.05.17 22:12
AlexNek
NEW 26.05.17 22:12 
в ответ moose 26.05.17 21:11
что треп в этом топике

Я вообще то думал что Вы имеете в виду совсем другой топик. Муркины проблемы не так просто классифицировать. Но в любом случае это задачки, хотя их и нужно довести до нормальной постановки.


Почему тогда уж сразу не Наполеон

Давайте жить дружно спок


#50 
  moose свой человек27.05.17 13:19
NEW 27.05.17 13:19 
в ответ AlexNek 26.05.17 22:12
Муркины проблемы не так просто классифицировать. Но в любом случае это задачки, хотя их и нужно довести до нормальной постановки.

То-то я и вижу, Вы с ним до хрипоты спорите, не можете определиться: кража или ограбление : )


PS. Интересно, кем вы оба были до революции...


#51 
AlexNek патриот27.05.17 15:56
AlexNek
NEW 27.05.17 15:56 
в ответ moose 27.05.17 13:19
Интересно, кем вы оба были до революции...

Увы похвасть нечем. Ананасов и рябчиковъ не жралисъ, за бананами на деревья не лазили. Хотя вот мурка вроде негром была.


Вы с ним до хрипоты спорите

Это со стороны видимо так наблюдается.

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

Жаркие были споры, но именно после них и рождалось более лучшее решение.

#52 
MrSanders старожил27.05.17 19:09
NEW 27.05.17 19:09 
в ответ moose 26.05.17 21:11

NB: влез исключительно от удивления сравнению архитектора с наполеоном.

Так Вы решили, что треп в этом топике - это "задачки где-то по архитектуре ПО"?

Может таковым оказаться. Если в конце не выяснится что ТС хотел узнать совсем другое, а все что он писал это так, от скуки.

Т.е. Вы - архитектор? Почему тогда уж сразу не Наполеон...

А откуда такой пиетет перед Software-архитекторами? Обычная работа. Или вы Enterprise-архитектора имели в виду? Но они не занимаются архитектурой ПО...

#53 
AlexNek патриот27.05.17 19:59
AlexNek
NEW 27.05.17 19:59 
в ответ MrSanders 27.05.17 19:09

Чтобы было немного ясно о чём спор (об архитектуре)

Начало было здесь

https://foren.germany.ru/showmessage.pl?Number=31946268&Bo...

"как и назвать использование DLL'ов "плигином".- Что отсылает совсем к другому топику (уже моему). Вот относительно него я и отвечал.


Ну а перехода на личности я стараюсь избегать, у каждого своя точка зрения и если она не совпадет с твоей собственной, то это не должно означать что другой "дурак".

Иногда можно просто иметь в виду совсем другое, а иногда представлять проблему в своем видении, ну и много чего другого.

#54 
  moose свой человек27.05.17 20:46
NEW 27.05.17 20:46 
в ответ AlexNek 27.05.17 15:56, Последний раз изменено 27.05.17 20:52 (moose)
вот мурка вроде негром была.

Что значит былА?


Три тыссячи черррртей!!!



#55 
  moose свой человек27.05.17 20:54
NEW 27.05.17 20:54 
в ответ MrSanders 27.05.17 19:09
А откуда такой пиетет перед Software-архитекторами? Обычная работа. Или вы Enterprise-архитектора имели в виду? Но они не занимаются архитектурой ПО...

Ну вот и Йентерпрайз-архитектор к нам соизволили. В палате становится тесновато : (


#56 
AlexNek патриот27.05.17 21:15
AlexNek
NEW 27.05.17 21:15 
в ответ moose 27.05.17 20:46
Что значит былА?

Патамушта - МуркА спок

#57 
  moose свой человек27.05.17 22:05
NEW 27.05.17 22:05 
в ответ AlexNek 27.05.17 21:15

Но там ясно написано: Мурр (он!)

#58 
AlexNek патриот27.05.17 23:00
AlexNek
NEW 27.05.17 23:00 
в ответ moose 27.05.17 22:05
Но там ясно написано: Мурр (он!)

А что это для вас это имеет какой то большой смысл в данном случае? Что на этом нужно заострять внимание или просто больше не к чему придраться?

В предложении было использовано имя Мурка, скажем так, по поэтическим соображениям спок Может еще и все слова нужно правильно писать?

#59 
MrSanders старожил28.05.17 11:39
NEW 28.05.17 11:39 
в ответ moose 27.05.17 20:54

Что вы! Я такое же быдло как и вы! (с)

Простите, хама трамвайного обыкновенного в вас сразу не распознал.

#60 
  moose свой человек28.05.17 12:48
NEW 28.05.17 12:48 
в ответ MrSanders 28.05.17 11:39

Ну архитектор зажигает! Полный пиетет!

#61 
MrSanders старожил28.05.17 13:25
NEW 28.05.17 13:25 
в ответ moose 28.05.17 12:48

А-а-а... вы просто значения слова пиетет не знаете и поэтому подумали что я вас как-то обозвал?

Пожалуйста, просвещайтесь:

пиете́т - Глубокое уважение, почтительное отношение к кому-л., чему-л.

#62 
  moose свой человек28.05.17 16:26
NEW 28.05.17 16:26 
в ответ MrSanders 28.05.17 13:25
значения слова пиетет не знаете

Где нам убогим, мы по этнерпрайсам не бываем : )


#63 
MrSanders старожил28.05.17 17:14
NEW 28.05.17 17:14 
в ответ moose 28.05.17 16:26

Ничего, не расстраивайтесь. Это не страшно. Быдлячить отучитесь, словарный запас увеличите, хорошим специалистом станете и вас обязательно пригласят.

Но возвращаясь к моему вопросу: может скажете что вас так удивило в том, что в эту ветку может заглянуть архитектор?

#64 
  moose свой человек28.05.17 22:35
NEW 28.05.17 22:35 
в ответ MrSanders 28.05.17 17:14

Заглянуть, безусловно, может. Но пока этого не произошло. Быдло одно, как Вы сами себя обозначили (и Вы правы, наверное). Можете больше не тужиться, я на Вас больше не отреагирую.

#65 
MrSanders старожил29.05.17 12:00
NEW 29.05.17 12:00 
в ответ moose 28.05.17 22:35, Последний раз изменено 29.05.17 12:06 (MrSanders)
Заглянуть, безусловно, может. Но пока этого не произошло.

Ну почему же. Я уже заглянул.

Быдло одно, как Вы сами себя обозначили (и Вы правы, наверное).

Передергиваете. Быдлом я называл только вас (или вы и процитированный мною анекдот не знаете?). А кроме вас в этой ветке и другие люди пишут.

Можете больше не тужиться, я на Вас больше не отреагирую.

Ничего страшного. Форум открытый, остальные почитают.

#66 
Murr_0002 постоялец01.06.17 17:43
Murr_0002
NEW 01.06.17 17:43 
в ответ MrSanders 29.05.17 12:00

N.P.


Таки Я молодец и таки Я собрал работающую схему многопоточки...

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

Быстро - эtо, что ранее на этом же хосте (И5-2320, 8Гб РАМ и ССД) в 1 поток делалось за 20-25 секунд, сейчас в 10 потоков делается за 0.9 секунды.

Меня - устраивает, но нужно посмотреть как скажется изменение количества потоков на работе системы.


Нужно еще разобраться с двумя моментами - те самые параметры (они уже есть, но не устраивает имплементация)

и управление выводом - тут надо иметь возможность дампить в сеть без записи на диск... или эмулировать диск в памяти...


По последнему есть вопросик - кто-нибудь видел имплементацию эмулятора диска, способного представлять файлами внешние по отношению к эмулятору, МемориСтреамы? Не хочется привязываться к файловой системе - нужно просто имя и возможность блочно читать МемориСтреам...

#67 
1 2 3 4 все