Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.10.2010, 21:37   #1
q_proger
Пользователь
 
Регистрация: 10.10.2010
Сообщений: 48
По умолчанию Асинхронный вызов в C#

Здравствуйте, уважаемые кодеры!
Возникла трудная ситуация в C#, надеюсь получить от вас подсказку или совет.
Задача такая: надо вызывать функцию асинхронно, делаю так, например:
Код:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Diagnostics;

namespace ConsoleApplication2
{
    delegate void fDel (object x);

    class Program
    {
        static Stopwatch sw;
        const int n = 10;

        static void f(object x)
        {
            Console.WriteLine(sw.Elapsed + ", вход в функцию f с индексом " + x.ToString());
            Thread.Sleep(1000); // идет какая-то работа...
        }

        static void Main()
        {
            sw = Stopwatch.StartNew();
            for (int i = 0; i < n; i++)
            {
                new fDel(f).BeginInvoke(i, null, null);
            }
            Console.WriteLine(sw.Elapsed + " все потоки запущены");
            Console.ReadKey();
        }
    }
}
И получаю вот такой вывод:
00:00:00.0028317 все потоки запущены
00:00:00.0030933, вход в функцию f с индексом 0
00:00:00.0085026, вход в функцию f с индексом 1
00:00:01.0079474, вход в функцию f с индексом 2
00:00:01.0667081, вход в функцию f с индексом 3
00:00:01.0695319, вход в функцию f с индексом 4
00:00:01.5062641, вход в функцию f с индексом 5
00:00:02.0060604, вход в функцию f с индексом 6
00:00:02.0089810, вход в функцию f с индексом 7
00:00:02.0675756, вход в функцию f с индексом 8
00:00:02.0708866, вход в функцию f с индексом 9
Т. е. куда-то просто выбрасывается две секунды, при том, что мне крайне важна производительность. Пробовал делать с пулом по примеру из статьи с rsdn, но результат ровно такой же, наверное что-то не учел.
Подскажите пожалуйста, на что здесь обратить внимание..
q_proger вне форума Ответить с цитированием
Старый 24.10.2010, 21:57   #2
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Все решается маленьким поиском
BOBAH13 вне форума Ответить с цитированием
Старый 27.10.2010, 19:28   #3
q_proger
Пользователь
 
Регистрация: 10.10.2010
Сообщений: 48
По умолчанию

Статья не о чем. Один человек сказал в комментариях "Don’t use the delegate BeginInvoke method to kick off lots of small pieces of work because the code behind the method uses very slow Reflection APIs" ну так я это и так вижу, и пример привел.
Я спрашивал как можно сделать по-другому, чтобы работало хорошо.

Или .net в принципе не способен на хорошую производительность?

Последний раз редактировалось q_proger; 27.10.2010 в 19:31.
q_proger вне форума Ответить с цитированием
Старый 30.10.2010, 18:17   #4
elja_1989
Пользователь
 
Регистрация: 16.03.2010
Сообщений: 58
По умолчанию

операция создания потоков крайне ресурсоемкая.. поэтому рекомендуется использовать пулы потоки которых не создаются более одного раза.. а когда поточная функция отработает они "ложатся отдыхать"
elja_1989 вне форума Ответить с цитированием
Старый 01.11.2010, 19:04   #5
q_proger
Пользователь
 
Регистрация: 10.10.2010
Сообщений: 48
По умолчанию

elja_1989 спасибо! Я подозревал, что как-то так и стоит делать, но пока не разобрался как именно, а впрочем это уже не актуально
q_proger вне форума Ответить с цитированием
Старый 14.12.2010, 00:51   #6
q_proger
Пользователь
 
Регистрация: 10.10.2010
Сообщений: 48
По умолчанию

Если кому-то будет интересна эта тема, отличной производительности в решении подобных задач можно достичь работая с методами System.Threading.Monitor.
А вот тут http://www.rsdn.ru/article/dotnet/CSThreading1.xml хорошо обо всем этом написано.
q_proger вне форума Ответить с цитированием
Старый 15.12.2010, 14:49   #7
sergei64_89
Форумчанин
 
Регистрация: 20.04.2008
Сообщений: 139
По умолчанию

с консолья не работал.но begininvoke всего лишь выполняет метод в том потоке где создан объект вызывающий этот инвок.а monitor это уже многопоточность.обычно люди выполняют вычисления в потоках,потом уже с помощью асинхронного вызова на форму выводят результат
sergei64_89 вне форума Ответить с цитированием
Старый 16.12.2010, 23:27   #8
q_proger
Пользователь
 
Регистрация: 10.10.2010
Сообщений: 48
По умолчанию

Не силен в этих тонкостях, но если бы BeginInvoke вызывал функцию "f" в том потоке, в котором был создан объект-делегат, в который она завернута, то есть в главном потоке, то никакого параллелизма бы не было, строки появлялись бы с интервалом в секунду.
То, что вы описали, верно для
Код:
IAsyncResult Control.BeginInvoke(Delegate method, params object[] args)
вызываемого в контексте объекта
Код:
System.Windows.Forms.Control
но не для
Код:
IAsyncResult BeginInvoke(arguments, AsyncCallback callback, object AsynState)
вызываемого в контексте объекта-делегата.

Последний раз редактировалось q_proger; 16.12.2010 в 23:30.
q_proger вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Асинхронный режим работы в WinSock ImmortalAlexSan Работа с сетью в Delphi 2 28.04.2011 22:19
Странное поведение WriteFile / WriteFileEx (асинхронный I/O) besserebrenik Win Api 0 22.02.2010 20:37
Асинхронный просмотр Claster Помощь студентам 6 11.02.2010 15:38
Асинхронный сокет raspberry C/C++ Сетевое программирование 8 07.07.2009 16:51
Асинхронный ввод/вывод Pblog Обсуждение статей 0 27.05.2007 02:13