Немножко вне рутины...
Предлагаю переименовать метод getresult() в getSUPERresult(), и все сразу пойдет : )
Это очень важно: назвать метод/переменную так, чтобы ни один шпион не догадался, что там и почему. Назвать класс "Process", и дать ему метод "Execute" (или как там?) - тоже хороший ход, как и назвать использование DLL'ов "плигином". Ребята, извините, но похоже, Вы тут только двое друг друга и понять можете ("неординарно мыслите"). Только зачем форум грузить?
как и назвать использование DLL'ов "плигином"
Можно назвать и "динамически загружаемые объекты", но все же
https://msdn.microsoft.com/en-us/library/ms972962.aspx
Да и название не играет в данном случае большой роли, сама проблема более интересна, хотя да не всем.
Только зачем форум грузить?
Мне кажется коллективная работа всегда интересней индивидуальной, да и в последнее время почти ничего нового и нет.
Неужели задачки не интересно порешать?
Как-то оно близко коррелирует с твоими запросами к загрузке плагинов.
Особой корреляции не вижу, кроме вопроса со стороны "а нахрена это всё нужно"
и это совершенно никак не относится к решаемой этим кодом задаче.
Код то производит запись в поток, значит как раз то очень и относится.
Можно переписать немного по другому
GetResult("B2"); --> writer.StoreData(typeof(B2));
Где writer не поток а твой класс, а каждая Бэшка реализует интерфейс IStoreData
Только зачем форум грузить?
------
Хммм... А зачем же форум существует? Чтобы в него НЕ писать?
Мне вот почему-то кажется, что хотя бы пара-тройка человек порадовалась тому, что найдено тривиальное решение не вполне тривиальной задачки.
Я, кстати, думал, что будет несколько сложнее.
Ну теперь следующий шаг - поженить этот код с бакгроундворкером и разнести Бешки по разным либам.
Разве не интересно - будет оно жить или где-то сломается?
назвать метод/переменную так
------
Есть у меня несколько сильно обфусканных сторонних дллок - там имена методов - _а4(), _а5()...
Да еще и полностью декомпилировать не получается - кусок связанный с идентификацией юсера и машины - сплошная ошибка декомпиляции.
Так что радуйся Процессу и Екзекуте...
-----
Интересней - может быть и нет, но всегда будет продуктивнее - Одна голова хорошо, а 1<<1 - лучше.
Неужели задачки не интересно порешать?
-----
Мне временами кажется, что нынешнему поколению действительно не интересно порешать задачки.
Т.е. работают они как чистые исполнители - объяснили что делать, объяснили как делать - работают.
Чуть только задача выпадает из области полученных разъяснений - тупик... сами - ни-ни... ждут пока
все пояснят... Может оно и правильно...
Мне временами кажется, что нынешнему поколению действительно не интересно порешать задачки.Т.е. работают они как чистые исполнители - объяснили что делать, объяснили как делать - работают.Чуть только задача выпадает из области полученных разъяснений - тупик... сами - ни-ни... ждут покавсе пояснят... Может оно и правильно...
Эй, ты, "вчерашнее поколение", если я тебе не тыкаю (в этот раз только сделаю исключение), то это не от возраста, а от воспитания. Чтобы мудрость из себя изображать, нужно для этого основания какие-то иметь, у Вас их нет.
Код то производит запись в поток, значит как раз то очень и относится.
-----
Код должен породить текст.
Вот тот текст, который порождается, меня интересует и интересует очень и очень сильно.
Именно то, какой текст будет порожден кодом и насколько сложно будет модифицировать
порождаемый код и составляет проблему.
То, как это будет реализовано технически - интересует только с позиции чтобы оно никак не
влияло на решение основной задачи.
Т.е. если мне для решения задачи не нужно знать об стреаме, не нужно его передавать или
еще как-то упоминать - это, несомненно, плюс.
Аналогично и по параметрам (тут не использовались) - если они НЕ болтаются под руками
- это тоже плюс.
Можно переписать немного по другому
-----
Можно. И даже - будет работать. Мало того - даже пару раз за последние полгода использовал
именно этот формат - нужно было обойти ошибку в подстановке значения с апострофами в
СКЛ. Но это было две строки на 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
-----
Можно. Нужно только поменять компилятор шаблонов. Или писать это дело руками для каждого класса...
Погонял в многопоточном режиме - все работает... На удивление - работает и работает нормально.
Видимо мелкомягкие сумели где-то спереть приличную реализацию потоков...
Вроде - уже постил, но что-то не вижу... видимо германка глючит...
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 threadb2.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 в пулл по окончании работы.
А где здесь задачки?
К сожалению, я не знаю, что вам интересно и какой примерно тип мышления у вас. Поэтому подобрать стиль ответа непросто.
По моему мнению, задачки где то по "архитектуре ПО", вполне допускаю, что это вас абсолютно не интересует. А задачками будет типа "сделать прогу выводящую свой код".
Может Вы тогда приведёте пример задачи по Вашему?
но пока не требовалось получать доступ к полям объекта после выполнения работы.
Ничего не понял точно. Но если тебе нужно что то получить из завершившего свою работу потока, то кинь ему класс с началом работы, пусть пишет всё что тебе нужно. Оттуда и заберешь. Или еще можно копию данных через евент отослать.
Или еще можно копию данных через евент отослать.
-----
Угу...
Такой евент уже написан в БэкгроундВоркере.
Только вот у меня получить в нем копию данных не получается...
из завершившего свою работу потока
------
Будь, кстати, остопрожен - из завершившегося потока уже ничего получить нельзя...
Можно получить перед завершением. но 100% - синхронно.
Ну так и не привязывай это дело к первоначальной задаче.
стоп, стоп. У меня была информация только о задаче 1 и ёё я и пытался решать безо всякого контекста.
Теперь ты предлагаешь задачу 2..
Видмо тебе нужно решить задачу 3, но ты этого еще не можешь объяснить
стоп, стоп. У меня была информация только о задаче 1 и ёё я и пытался решать безо всякого контекста.
Теперь ты предлагаешь задачу 2..
-----
Возьми третью часть того поста - там где один из первых врапится - и реши ее через предлагаемый тобой вариант.
Потом сравни с тем что приведено в третьем блоке кода.
Где будет ПРОЩЕ?
Ну теперь представь, что ЭТО будет ваять... хммм... ну вон хоть Мышонок....
Может там еще упростить? До уровня <# GetResult("B2") #>? Меня ведь интересует только подстановка результата по месту написания с минимальными затратами.
Видмо тебе нужно решить задачу 3, но ты этого еще не можешь объяснить
-----
Таки - да, есть следующий фрагмент - уработать выше показанное в компактненькую и флексибилитную подсистемку генерации.
Ну там еще будет 3.а, 3.б, 4.а.б.ц.д.е... 556.а и т.п.
На то она и разработка...