При запуске нового потока в С++ ему передается в качестве аргумента указатель (void*), в который размещаются все необходимые данные.
При запуске нового потока в C# используется делегат ThreadStart(), который аргументов не принимает. Передать данные я смог только через статические поля класса, метод которого использовался для запуска потока.
Есть ли возможность запустить новый поток в C#, передав ему в каческве аргумента object?
Если есть, то как?
Здравствуйте, <Аноним>, Вы писали:
А>При запуске нового потока в С++ ему передается в качестве аргумента указатель (void*), в который размещаются все необходимые данные. А>При запуске нового потока в C# используется делегат ThreadStart(), который аргументов не принимает. Передать данные я смог только через статические поля класса, метод которого использовался для запуска потока.
А>Есть ли возможность запустить новый поток в C#, передав ему в каческве аргумента object? А>Если есть, то как?
Здравствуйте, Аноним, Вы писали:
А>Есть ли возможность запустить новый поток в C#, передав ему в каческве аргумента object? А>Если есть, то как?
public void Start (object parameter)
О так?
Многопоточность
От:
Аноним
Дата:
05.09.06 09:39
Оценка:
public class Main
{
public Main()
{
CustomThread customThread = new CustomThread(new string[]{"1", "2", "3"});
Thread thread = new Thread(new ThreadStart(customThread.Start));
}
public void ThreadWorker()
{
}
}
public class CustomThread
{
private object _data;
public object Data
{
get
{
return _data;
}
}
public CustomThread(object data)
{
this._data = data;
}
public void Start()
{
// do smth with _data
}
}
Error 5 The call is ambiguous between the following methods or properties: 'System.Threading.Thread.Thread(System.Threading.ThreadStart)' and 'System.Threading.Thread.Thread(System.Threading.ParameterizedThreadStart)'
Здравствуйте, UFB, Вы писали:
UFB>Здравствуйте, AndrewVK, Вы писали:
AVK>>Здравствуйте, <Аноним>, Вы писали:
AVK>>Еще один вариант — использовать замыкание:
AVK>>
Это все конечно круто, но вот только работать не будет. т.к. замыканий в C# пока нет
string str = "This is a test!";
ThreadStart ts = new ThreadStart(delegate() { Method(str); });
Thread t = new Thread(ts);
str = "This is a second test!";
t.Start();
t.Join();
static void Method(string str)
{
Console.WriteLine(str);
}
Здравствуйте, Lloyd, Вы писали:
ie>>Это все конечно круто, но вот только работать не будет. т.к. замыканий в C# пока нет ie>>
ie>> string str = "This is a test!";
ie>> ThreadStart ts = new ThreadStart(delegate() { Method(str); });
ie>> Thread t = new Thread(ts);
ie>> str = "This is a second test!";
ie>> t.Start();
ie>> t.Join();
ie>> static void Method(string str)
ie>> {
ie>> Console.WriteLine(str);
ie>> }
ie>>
L>Вау, это новое слово в аргументировании — приводит пример замыкания для доказательсятва отсутствия оных.
Вот когда этот пример выведет в консоль "This is a test!", тогда это будут замыкания, а пока выводит "This is a second test!", это пример отсутсвия оных
Здравствуйте, AndrewVK, Вы писали:
ie>>Это все конечно круто, но вот только работать не будет. т.к. замыканий в C# пока нет
AVK>Если ты не знаешь особенностей строк в дотнете, то это не значит что там замыканий нет.
А какая такая особенность строк здесь используется?
Здравствуйте, AndrewVK, Вы писали:
ie>>Это все конечно круто, но вот только работать не будет. т.к. замыканий в C# пока нет AVK>Если ты не знаешь особенностей строк в дотнете, то это не значит что там замыканий нет.
А причем тут собственно строки? Я могу вместо строки взять любой другой объект, результат от этого не изменется.
Здравствуйте, ie, Вы писали:
L>>Вау, это новое слово в аргументировании — приводит пример замыкания для доказательсятва отсутствия оных.
ie>Вот когда этот пример выведет в консоль "This is a test!", тогда это будут замыкания, а пока выводит "This is a second test!", это пример отсутсвия оных
Нет, это не отсутствие оных, а непонимание того, что такое замыкание. Замыкание захватывает переменную, а не её значение.
Здравствуйте, Lloyd, Вы писали:
L>>>Вау, это новое слово в аргументировании — приводит пример замыкания для доказательсятва отсутствия оных. ie>>Вот когда этот пример выведет в консоль "This is a test!", тогда это будут замыкания, а пока выводит "This is a second test!", это пример отсутсвия оных L>Нет, это не отсутствие оных, а непонимание того, что такое замыкание. Замыкание захватывает переменную, а не её значение.
Здравствуйте, ie, Вы писали:
ie>А причем тут собственно строки?
А при чем тут собственно то, что в C# замыкания read-only? Вопрос был про передачу параметров в поток, а не про возврат оттуда.
При необходимости всегда можно передать mutable объект (C# ведь не функциональный язык, в нем это вполне естественно) и менять его, не меняя ссылки. Но к исходному вопросу это никакого отношения не имеет.
Здравствуйте, AndrewVK, Вы писали:
ie>>А причем тут собственно строки? AVK>А при чем тут собственно то, что в C# замыкания read-only? Вопрос был про передачу параметров в поток, а не про возврат оттуда.
Дык, я оттуда ничего вернуть и не пытаюсь. Разве не так?
AVK>При необходимости всегда можно передать mutable объект (C# ведь не функциональный язык, в нем это вполне естественно) и менять его, не меняя ссылки. Но к исходному вопросу это никакого отношения не имеет.
Мы уже с Lloyd выяснили, что я не правильно понимал замыкания. Я полагал, что используется значение которое было в момент создания делегата, а не в момент его вызова. Оказалось ровно наоборот.
Здравствуйте, Lloyd, Вы писали:
L>И как она здесь используется? Переделай на любой другой класс, результат будет тот же.
StringBuilder str = new StringBuilder("This is a test!");
ThreadStart ts = new ThreadStart(delegate() { Method(str); });
Thread t = new Thread(ts);
str.Length = 0; str.Append("This is a second test!");
t.Start();
t.Join();
Здравствуйте, Lloyd, Вы писали:
AVK>>А при чем тут собственно то, что в C# замыкания read-only?
L>
Хочешь поспорить о терминах? Имелось ввиду, что изменение замыканий во внешнем контексте после его образования не распространяется на внутренний, что, собственно, приведенный пример и демонстрировал.
AVK> StringBuilder str = new StringBuilder("This is a test!");
AVK> ThreadStart ts = new ThreadStart(delegate() { Method(str); });
AVK> Thread t = new Thread(ts);
AVK> str.Length = 0; str.Append("This is a second test!");
AVK> t.Start();
AVK> t.Join();
AVK>
Не, такие лоховские подтасовки не катят. Пиши тогда уж:
str = new StringBuilder("This is a second test!");
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Lloyd, Вы писали:
AVK>>>А при чем тут собственно то, что в C# замыкания read-only?
L>>
AVK>Хочешь поспорить о терминах? Имелось ввиду, что изменение замыканий во внешнем контексте после его образования не распространяется на внутренний, что, собственно, приведенный пример и демонстрировал.
А можно то же самое, но на русском языке. Что значит "изменение замыканий"? Для меня замыкание — это совокупность "захваченных" переменных. Как он может измениться?
Здравствуйте, Lloyd, Вы писали:
L>Не, такие лоховские подтасовки не катят. Пиши тогда уж:
Что то у тебя с терминологией не то. Подтасовок тут никаких нет, всего лишь демонстрация того, как нужно действовать, когда таки хочется получить требуемое. Только, конечно, лучше не StringBuilder использовать, а специальный mutable класс. А еще лучше вобще такое не использовать, ибо чревато.
Здравствуйте, Lloyd, Вы писали:
L>А можно то же самое, но на русском языке. Что значит "изменение замыканий"? Для меня замыкание — это совокупность "захваченных" переменных. Как он может измениться?
Я лучше на английском процитирую:
any changes to such variables from within the body of anonymous method are not visible after it returns. This is because anonymous methods are in fact implemented in a way very similar to anonymous inner classes in Java, and do not have direct access to variables from the enclosing scope; rather, the method makes a copy of all local variables it uses.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Lloyd, Вы писали:
L>>Не, такие лоховские подтасовки не катят. Пиши тогда уж:
AVK>Что то у тебя с терминологией не то. Подтасовок тут никаких нет, всего лишь демонстрация того, как нужно действовать, когда таки хочется получить требуемое.
Только вот требуемого поведения таким способом не получить. Смотри первоначальный пост.
Здравствуйте, AndrewVK, Вы писали:
L>>А можно то же самое, но на русском языке. Что значит "изменение замыканий"? Для меня замыкание — это совокупность "захваченных" переменных. Как он может измениться?
AVK>Я лучше на английском процитирую: AVK>
any changes to such variables from within the body of anonymous method are not visible after it returns. This is because anonymous methods are in fact implemented in a way very similar to anonymous inner classes in Java, and do not have direct access to variables from the enclosing scope; rather, the method makes a copy of all local variables it uses.
Ну, во-первых, тебе привели пример того, что изменения захваченные переменных все-таки видны после возврата из метода. А во-вторых, причем здесь джава?
Здравствуйте, Lloyd, Вы писали:
L>Ну, во-первых, тебе привели пример того, что изменения захваченные переменных все-таки видны после возврата из метода.
Мне не надо.
L> А во-вторых, причем здесь джава?
При том, что текст, оказавшийся под рукой, был заодно и про Java.
Здравствуйте, AndrewVK, Вы писали:
L>>Ну, во-первых, тебе привели пример того, что изменения захваченные переменных все-таки видны после возврата из метода.
AVK>Мне не надо.
Чего не надо? Твои слова опровергаются простейшим тестом.
L>> А во-вторых, причем здесь джава?
AVK>При том, что текст, оказавшийся под рукой, был заодно и про Java.
Но, как минимум, по отношению к .net-у он не верен.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Lloyd, Вы писали:
L>>Чего не надо? Твои слова опровергаются простейшим тестом.
AVK>Это спор о терминах.
Хорошо, напиши по-русски как ты понял приведенную цитату. Вот мой перевод:
любые именения этих переменных, сделанные внутри тела анонимного метода не видны после возврата из анонимного метода. Так происходит потому что анонимные методы в действительности реализованы способом, очень схожим с тем как реализованы inner-классы в джаве. и (анонимные методы) не имеют прямого доступа к переменным из внешней области видимости; метод создает копию всех локальных переменных, которые он ипользует.
Если я не наврал в переводе, то то что там написано не соответствует действительности.
AVK>>>При том, что текст, оказавшийся под рукой, был заодно и про Java.
L>>Но, как минимум, по отношению к .net-у он не верен.
AVK>Конкретно в цитате про C#.
Здравствуйте, Lloyd, Вы писали:
L>Да я прекрасно знаю как работают замыкания. А вот судя по твоим высказываниям, у тебя в этой области есть определенные пробелы.
Понятно, заняться не чем. В следующий раз разводить в форуме черти что не нужно, достаточно написать свое фе мне лично на сыло.
Здравствуйте, AndrewVK, Вы писали:
L>>Да я прекрасно знаю как работают замыкания. А вот судя по твоим высказываниям, у тебя в этой области есть определенные пробелы.
AVK>Понятно, заняться не чем. В следующий раз разводить в форуме черти что не нужно, достаточно написать свое фе мне лично на сыло.
До этой ветки никакого моего фе по отношению к вам не было. Так что не смог бы воспользоваться вашим советом при всем желании.
Здравствуйте, AndrewVK, Вы писали:
AVK>Понятно, заняться не чем. В следующий раз разводить в форуме черти что не нужно, достаточно написать свое фе мне лично на сыло.
Тем не менее можно все-таки объяснить на примере каким образом замыкания бывают "только для чтения"? Если мне не изменяет память переменные используемые одноврменно в контексте родительского метода и анонимного при компиляции превращаются в поля класса, соответственно, менять их пределах области видимости класса можно откуда угодно.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Тем не менее можно все-таки объяснить на примере каким образом замыкания бывают "только для чтения"? Если мне не изменяет память переменные используемые одноврменно в контексте родительского метода и анонимного при компиляции превращаются в поля класса, соответственно, менять их пределах области видимости класса можно откуда угодно.
Да лажанулся чувак. Толко признаваться в этом очень не хочется, модератор все-таки.
Здравствуйте, ie, Вы писали:
ie>Здравствуйте, AndrewVK, Вы писали:
ie>>>А причем тут собственно строки? AVK>>А при чем тут собственно то, что в C# замыкания read-only? Вопрос был про передачу параметров в поток, а не про возврат оттуда.
ie>Дык, я оттуда ничего вернуть и не пытаюсь. Разве не так?
AVK>>При необходимости всегда можно передать mutable объект (C# ведь не функциональный язык, в нем это вполне естественно) и менять его, не меняя ссылки. Но к исходному вопросу это никакого отношения не имеет.
ie>Мы уже с Lloyd выяснили, что я не правильно понимал замыкания. Я полагал, что используется значение которое было в момент создания делегата, а не в момент его вызова. Оказалось ровно наоборот.
Выше сказанное абсолютно правильно. Маленькое дополнение — цитата из Ecma-334:
14.5.15.2 Anonymous method blocks
...
The block has access to the outer variables (§14.5.15.3) of the anonymous method. Access of an outer
variable will reference the instance of the variable that is active at the time the anonymous-methodexpression
is evaluated (§14.5.15.4).
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Многопоточность
От:
Аноним
Дата:
14.09.06 14:55
Оценка:
Здравствуйте, Аноним, Вы писали:
А>При запуске нового потока в С++ ему передается в качестве аргумента указатель (void*), в который размещаются все необходимые данные. А>При запуске нового потока в C# используется делегат ThreadStart(), который аргументов не принимает. Передать данные я смог только через статические поля класса, метод которого использовался для запуска потока.
А>Есть ли возможность запустить новый поток в C#, передав ему в каческве аргумента object? А>Если есть, то как?
Люди, а что велик-то изобретаем?! Для этого в каждом потоке есть слоты данных.
А именно:
1. создал поток (он ещё не запущен)
2. создал слот
3. записал в слот
4. запустил поток
5. получил данные из запущенного потока Thread.CurrentThread.GetData (...)
6. убил слот
Да тут все еще проще. На самом деле в дотнете 2.0, на котором изначально приводились примеры кода есть делегат ParameterizedThreadStart, который как и позволяет прекрасно решить обозначенную в первом топике задачу — без всяких там замыканий, слотов и другой медвежути.
Здравствуйте, <Аноним>, Вы писали:
А>Есть ли возможность запустить новый поток в C#, передав ему в каческве аргумента object? А>Если есть, то как?
можно так:
class TEST
{
static public void Main()
{
MyThreadData td = new MyThreadData();
td.str = "This is a test!";
Thread t = new Thread(td.threadProc);
t.Start();
t.Join();
}
class MyThreadData
{
public string str;
public void threadProc()
{
Console.WriteLine("{0}", str);
}
}
}
Тот кто знает не говорит, тот кто говорит не знает.
Здравствуйте, Streamer1, Вы писали:
S>объясните плиз: S>
S>delegate { Method(str); }
S>
S>что при этом реально происходит?
Реально компилятор генерит класс, который инкапсулирует все поля, которые используются в замыкании. Т.е. после компиляции приведенный мной код превратится примерно в следующее:
private static void Method(string str)
{
Console.WriteLine(str);
}
private static void Main(string[] args)
{
Temp temp = new Temp();
temp.str = "This is a test!";
ThreadStart start1 = new ThreadStart(temp.Method);
Thread thread1 = new Thread(start1);
temp.str = "This is a second test!";
thread1.Start();
thread1.Join();
Console.ReadLine();
}
private sealed class Temp
{
public string str;
public void Method()
{
Test.Method(str);
}
}
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Да тут все еще проще. На самом деле в дотнете 2.0, на котором изначально приводились примеры кода есть делегат ParameterizedThreadStart, который как и позволяет прекрасно решить обозначенную в первом топике задачу — без всяких там замыканий, слотов и другой медвежути.
Замыкание позволяет обойтись без приведений типов.
Здравствуйте, ie, Вы писали:
ie>Реально компилятор генерит класс, который инкапсулирует все поля, которые используются в замыкании. Т.е. после компиляции приведенный мной код превратится примерно в следующее: ie>
...
ie> private sealed class Temp
ie> {
ie> public string str;
ie> public void Method()
ie> {
ie> Test.Method(str);
ie> }
ie> }
ie>
хм... а я такой класс сам пишу в таких случаях
Тот кто знает не говорит, тот кто говорит не знает.