Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5

Многопоточность с использованией С# 5

16.03.2013, 21:57. Показов 1861. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пытаюсь разобраться, пишу такой код:
окошко:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<Window x:Class="AsyncLoading.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Loaded="MainWindow_OnLoaded">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBox Name="Tb1"/>
        <TextBox Name="Tb2" Grid.Column="1"/>
        <TextBox Name="Tb3" Grid.Column="2"/>
    </Grid>
</Window>
собственно код
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
using System;
using System.Net;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
 
namespace AsyncLoading
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
 
        private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
        {
            const string bashOrgRu = @"http://bash.org.ru/abyssbest";
            const string ithappens = @"http://ithappens.ru/";
            const string cyberForum = @"https://www.cyberforum.ru/csharp-net/";
            Action<string, TextBox> sendRequest = async (site, box) =>
                {
                    var wr = WebRequest.Create(site);
                    WebResponse webResponse = await wr.GetResponseAsync();
                    box.Text = string.Format("{0}\r\n{1}\r\nThread Id: {2}", site, webResponse.ContentLength,
                                             Thread.CurrentThread.ManagedThreadId);
                };
            sendRequest(bashOrgRu, Tb1);
            sendRequest(ithappens, Tb2);
            sendRequest(cyberForum, Tb3);
        }
    }
}
он мне возвращает
1) Почему он один и тот же поток во всех случаях?
2) Почему ContentLength == -1?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
16.03.2013, 21:57
Ответы с готовыми решениями:

Прозрачное использованией WinXP машиной сетевых функций другого компьютера.
Привет всем! Представьте себе такую ситуацию. Есть два компьютера. Причём, один на WinXP, другой на Unix'е. Машина с юниксом...

Многопоточность в С++
Добрый день! Если я создам экземпляр класса в одном потоке и начну одновременно из нескольких других потоков обращаться тому...

Многопоточность
Имеется класс class MainMeneger: Form, в нем объявляются интерфейсы public IMainForm view; public IMessegeService messege; public...

13
Заблокирован
17.03.2013, 01:16
Цитата Сообщение от Psilon Посмотреть сообщение
box.Text = string.Format("{0}\r\n{1}\r\nThread Id: {2}", site, webResponse.ContentLength,
* * * * * * * * * * * * * * * * * * * * * * *Thread.CurrentThread.ManagedThreadId);
это строка выполнится в основном потоке, но после завершения асинхронного запроса. Если интересно почему, то можно повнимательней почитать документацию, а саму идею реализации подобного поведения Рихтер описал еще задолго до появления C# 5.0. Вот даже перевод имеется http://msdn.microsoft.com/ru-r... 46608.aspx

Добавлено через 1 минуту
Цитата Сообщение от Psilon Посмотреть сообщение
Почему ContentLength == -1?
пока думаю.. проверить негде.

Добавлено через 4 минуты
ILDasm.exe тебе в помощь. если сам не разберешь скинь сюда.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
17.03.2013, 01:29  [ТС]
loro, совершенно аналогичный код дает другой результат:
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
using System;
using System.Diagnostics;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
 
namespace ConsoleApplication8
{
    class Program
    {
        async static void AsyncVersion()
        {
            Stopwatch sw = Stopwatch.StartNew();
            string url1 = "http://rsdn.ru";
            string url2 = "http://gotdotnet.ru";
            string url3 = "http://blogs.msdn.com";
 
            var webRequest1 = WebRequest.Create(url1);
            Console.WriteLine("Before webRequest1.GetResponseAsync(). Thread Id: {0}",
                Thread.CurrentThread.ManagedThreadId);
 
            var webResponse1 = await webRequest1.GetResponseAsync();
            Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url1,
                webResponse1.ContentLength, sw.ElapsedMilliseconds,
                Thread.CurrentThread.ManagedThreadId);
 
            var webRequest2 = WebRequest.Create(url2);
            Console.WriteLine("Before webRequest2.GetResponseAsync(). Thread Id: {0}",
                Thread.CurrentThread.ManagedThreadId);
 
            var webResponse2 = await webRequest2.GetResponseAsync();
            Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url2,
                webResponse2.ContentLength, sw.ElapsedMilliseconds,
                Thread.CurrentThread.ManagedThreadId);
 
            var webRequest3 = WebRequest.Create(url3);
            Console.WriteLine("Before webRequest3.GetResponseAsync(). Thread Id: {0}",
                Thread.CurrentThread.ManagedThreadId);
            var webResponse3 = await webRequest3.GetResponseAsync();
            Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url3,
                webResponse3.ContentLength, sw.ElapsedMilliseconds,
                Thread.CurrentThread.ManagedThreadId);
        }
        static void Main(string[] args)
        {
 
            try
            {
                Console.WriteLine("Main thread id: {0}", Thread.CurrentThread.ManagedThreadId);
                Task task = new Task(AsyncVersion);
                task.Start();
                Console.WriteLine("Right after AsyncVersion() method call");
                //Ожидаем завершения асинхронной операции
                task.Wait();
                Console.WriteLine("Asyncronous task finished!");
 
            }
            catch (System.AggregateException e)
            {
                //Все исключения в TPL пробрасываются обернутые в AggregateException
                Console.WriteLine("AggregateException: {0}", e.InnerException.Message);
            }
            Console.ReadLine();
        }
    }
}
0
Заблокирован
17.03.2013, 03:52
при выполнении асинхронного метода запрашивается контекст планирования потока, в котором он выполняется, т.е. что касается UI, то все что идет после завершения задачи гарантировано будет выполнено в UI потоке.

Т.е. все зависит от контекста планирования потока.
В консольном приложении код идущий после ожидания асинхронной операции выполняется в том потоке(поток берется из пула, поэтому в примере мы и имеем такой разброс ID), в котором собственно выполнялась асинхронная операция, т.к. по сути это тотже колбек.

все это можно прочитать вот тут: http://msdn.microsoft.com/ru-r... 56403.aspx
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
17.03.2013, 10:22  [ТС]
loro, ну то что в консоли и в GUI различается строгость к доступу из многопоточной программы я понимаю, но все равно непонятно...
Кстати, такой код у меня вообще ничего не делает:
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
using System;
using System.Net;
using System.Threading.Tasks;
using System.Windows;
 
namespace AsyncLoading
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
 
        private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
        {
            AsyncLoading();
        }
 
        private async void AsyncLoading()
        {
            const string bashOrgRu = @"http://bash.org.ru/abyssbest";
            const string ithappens = @"http://ithappens.ru/";
            const string cyberForum = @"https://www.cyberforum.ru/csharp-net/";
            Func<string, Task<string>> getRequest = site =>
                {
                    var wr = WebRequest.Create(site);
                    return new Task<string>(wr.GetResponseAsync().Result.ToString);
                };
            Tb1.Text = await getRequest(bashOrgRu);
            Tb2.Text = await getRequest(ithappens);
            Tb3.Text = await getRequest(cyberForum);
        }
    }
}
0
Заблокирован
17.03.2013, 13:43
Цитата Сообщение от Psilon Посмотреть сообщение
ну то что в консоли и в GUI различается строгость к доступу из многопоточной программы я понимаю, но все равно непонятно...
это тут вообще ни причем.

Добавлено через 8 минут
это код у тебя и не должен ничего делать.

Цитата Сообщение от Psilon Посмотреть сообщение
Tb1.Text = await getRequest(bashOrgRu);
тут запускаешь асинхронную операцию, которая в свое время запускает другую, но не дожидается результата ее выполнения. Да почитай статью внимательно(все там есть), вот ты все нахаляву хочешь получить.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
17.03.2013, 15:37  [ТС]
loro, при чем тут на халяву, если я тестовое приложение пишу тупо чтобы понять работу?
тут запускаешь асинхронную операцию, которая в свое время запускает другую, но не дожидается результата ее выполнения. Да почитай статью внимательно(все там есть), вот ты все нахаляву хочешь получить.
Спасибо, разобрался, исправил, заработало. Но все равно возвращает -1
0
Заблокирован
17.03.2013, 18:13
Цитата Сообщение от Psilon Посмотреть сообщение
loro, ну то что в консоли и в GUI различается строгость к доступу из многопоточной программы я понимаю, но все равно непонятно...
Кстати, такой код у меня вообще ничего не делает:
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
using System;
using System.Net;
using System.Threading.Tasks;
using System.Windows;
 
namespace AsyncLoading
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
 
        private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
        {
            AsyncLoading();
        }
 
        private async void AsyncLoading()
        {
            const string bashOrgRu = @"http://bash.org.ru/abyssbest";
            const string ithappens = @"http://ithappens.ru/";
            const string cyberForum = @"https://www.cyberforum.ru/csharp-net/";
            Func<string, Task<string>> getRequest = site =>
                {
                    var wr = WebRequest.Create(site);
                    return new Task<string>(wr.GetResponseAsync().Result.ToString);
                };
            Tb1.Text = await getRequest(bashOrgRu);
            Tb2.Text = await getRequest(ithappens);
            Tb3.Text = await getRequest(cyberForum);
        }
    }
}
Вам не правильно ответили, у вас проблема в том, что задачи созданные вами , не запускаются, а только создаются.
Делегат можно изменить так:
C#
1
2
3
4
5
6
7
  Func<string, Task<string>> getRequest = site =>
                {
                    var wr = WebRequest.Create(site);
Task<String> task=new Task<string>(wr.GetResponseAsync().Result.ToString);
task.Start();
                    return task;
                };
Добавлено через 8 минут
Цитата Сообщение от Psilon Посмотреть сообщение
Пытаюсь разобраться, пишу такой код:
окошко:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<Window x:Class="AsyncLoading.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Loaded="MainWindow_OnLoaded">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBox Name="Tb1"/>
        <TextBox Name="Tb2" Grid.Column="1"/>
        <TextBox Name="Tb3" Grid.Column="2"/>
    </Grid>
</Window>
собственно код
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
using System;
using System.Net;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
 
namespace AsyncLoading
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
 
        private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
        {
            const string bashOrgRu = @"http://bash.org.ru/abyssbest";
            const string ithappens = @"http://ithappens.ru/";
            const string cyberForum = @"https://www.cyberforum.ru/csharp-net/";
            Action<string, TextBox> sendRequest = async (site, box) =>
                {
                    var wr = WebRequest.Create(site);
                    WebResponse webResponse = await wr.GetResponseAsync();
                    box.Text = string.Format("{0}\r\n{1}\r\nThread Id: {2}", site, webResponse.ContentLength,
                                             Thread.CurrentThread.ManagedThreadId);
                };
            sendRequest(bashOrgRu, Tb1);
            sendRequest(ithappens, Tb2);
            sendRequest(cyberForum, Tb3);
        }
    }
}
он мне возвращает

1) Почему он один и тот же поток во всех случаях?
2) Почему ContentLength == -1?
1) Дело в том, что sendRequest запускается три раза в одном и том же потоке, и каждый раз его действие откладывается и управление возвращается из него сразу. В итоге один поток
2) У вас базовый клас WebResponse в нем не реализована эта функция, попорбуйте использовать его потомок HttpWebResponse
1
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
17.03.2013, 19:33  [ТС]
Urety, да ну?
1) в консольном приложении все потоки различаются (можете посмотреть сами при желании)
2) в консольном приложении ContentLength != -1, хотя выполняется тот же код.

А код я так исправил (до того, как ваш ответ прочитал):
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
using System;
using System.Net;
using System.Threading.Tasks;
using System.Windows;
 
namespace AsyncLoading
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
 
        private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
        {
            AsyncLoading();
        }
 
        private async void AsyncLoading()
        {
            const string bashOrgRu = @"http://bash.org.ru/abyssbest";
            const string ithappens = @"http://ithappens.ru/";
            const string cyberForum = @"https://www.cyberforum.ru/csharp-net/";
            Func<string, Task<WebResponse>> getRequest = site =>
                {
                    var wr = WebRequest.Create(site);
                    return wr.GetResponseAsync();
                };
            Tb1.Text = (await getRequest(bashOrgRu)).ContentLength.ToString();
            Tb2.Text = (await getRequest(ithappens)).ContentLength.ToString();
            Tb3.Text = (await getRequest(cyberForum)).ContentLength.ToString();
        }
    }
}
1
Заблокирован
17.03.2013, 20:50
Цитата Сообщение от Psilon Посмотреть сообщение
Urety, да ну?
1) в консольном приложении все потоки различаются (можете посмотреть сами при желании)
2) в консольном приложении ContentLength != -1, хотя выполняется тот же код.

А код я так исправил (до того, как ваш ответ прочитал):
Кликните здесь для просмотра всего текста
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
using System;
using System.Net;
using System.Threading.Tasks;
using System.Windows;
 
namespace AsyncLoading
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
 
        private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
        {
            AsyncLoading();
        }
 
        private async void AsyncLoading()
        {
            const string bashOrgRu = @"http://bash.org.ru/abyssbest";
            const string ithappens = @"http://ithappens.ru/";
            const string cyberForum = @"https://www.cyberforum.ru/csharp-net/";
            Func<string, Task<WebResponse>> getRequest = site =>
                {
                    var wr = WebRequest.Create(site);
                    return wr.GetResponseAsync();
                };
            Tb1.Text = (await getRequest(bashOrgRu)).ContentLength.ToString();
            Tb2.Text = (await getRequest(ithappens)).ContentLength.ToString();
            Tb3.Text = (await getRequest(cyberForum)).ContentLength.ToString();
        }
    }
}
1) Они не могут различаться, т.к. делегат запускается синхронно в главном потоке. Вы сказали посмотреть, посмотрел, один поток.
C#
1
2
3
4
5
6
  Func<string, Task<WebResponse>> getRequest = site =>
                {
                    this.Title += System.Threading.Thread.CurrentThread.ManagedThreadId.ToString();
                    var wr = HttpWebRequest.Create(site);
                    return wr.GetResponseAsync();
                };
2) На сколько я понял , оно будет всегда равно -1 в любом приложении, потому что это свойство читает заголовок ответа Http Content-Length, а он не всегда передается в ответе.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
17.03.2013, 21:27  [ТС]
loro, да ну, тогда почему стоило мне сменить сайты, так сразу и ответ поменялся?
Миниатюры
Многопоточность с использованией С# 5  
0
Заблокирован
17.03.2013, 21:33
Цитата Сообщение от Psilon Посмотреть сообщение
loro, да ну, тогда почему стоило мне сменить сайты, так сразу и ответ поменялся?
Может, потому, что в Http ответе с этих сайтов есть заголовок Content-length: с числом размера страницы.
1
 Аватар для LeniumSoft
1454 / 847 / 150
Регистрация: 06.06.2012
Сообщений: 2,370
18.03.2013, 10:00
Цитата Сообщение от Psilon Посмотреть сообщение
да ну, тогда почему стоило мне сменить сайты, так сразу и ответ поменялся?

Не по теме:

=-O Что ты сделал со своей студией!

0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
18.03.2013, 11:10  [ТС]
LeniumSoft,

Не по теме:

а что такое? :scratch:

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.03.2013, 11:10
Помогаю со студенческими работами здесь

Многопоточность
Доброго времени суток! Пишу довольно редко, самостоятельно не получилось разобраться:( Сразу перейду к задаче. Допустим есть цикл: ...

Многопоточность
Доброго времени суток! Прокомментируйте пожалуйста данный код по использованию потоков. В чем его минусы? Какие могут быть проблемы? ...

Многопоточность в VB
Добрый день. Ни как не получается заставить нормально работать код с двумя потоками. 1. Если убрать из кода строчку с...

Многопоточность
Нужно, чтобы memo заполнялось числами с помощью n-го количества потоков. Числа заполняются, только вот потоки некоректно работают (скорость...

Многопоточность
Как передать один и тот же параметр нескольким потокам. Есть 3 потока в них есть методы которые принимают на вхлд какую-либо строку. Как...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
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 https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru