Моно готов к прайм-тайм? [закрытый]


кто-нибудь использовал Mono, реализацию .NET с открытым исходным кодом на большом или среднем проекте? Мне интересно, готов ли он к реальному миру, производственной среде. Это стабильный, быстрый, совместимый, ... достаточно, чтобы использовать? Требуется ли много усилий для переноса проектов в среду выполнения Mono, или это действительно так,действительно достаточно совместим, чтобы просто взять и запустить уже написанный код для среды выполнения Microsoft?

17 313

17 ответов:

есть несколько сценариев для рассмотрения: (a) если вы портируете существующее приложение и задаетесь вопросом, достаточно ли моно для этой задачи; (b) вы начинаете писать новый код, и вы хотите знать, достаточно ли моно зрело.

в первом случае, вы можете использовать Mono Migration Analyzer tool (Moma), чтобы оценить, как далеко ваше приложение от запуска на моно. Если оценка возвращается с честью, вы должны начать тестирование и QA и приготовьтесь к отправке.

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

согласно нашей статистике Moma, основанной на представлениях пользователей (это из памяти), около 50% приложений работают из коробки, около 25% требуется около недели работы (рефакторинг, адаптация) еще 15% требуют серьезной приверженности повторению кусков вашего кода, а остальное просто не стоит беспокоиться о портировании, поскольку они так невероятно привязаны к Win32. В этот момент либо вы начинаете с нуля, либо бизнес-решение будет стимулировать усилия по переносу вашего кода, но мы говорим о месяцах работы (по крайней мере, из отчетов, которые у нас есть).

Если вы начинаете с нуля, то ситуация много проще, потому что вы будете использовать только API, которые присутствуют в Mono. Пока вы остаетесь с поддерживаемым стеком (который в значительной степени .NET 2.0, а также все основные обновления в 3.5, включая LINQ и System.Ядро, плюс любой из моно кросс-платформенных API) вы будете в порядке.

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

Что касается переносимости: ASP.NET приложения легче переносить, так как они практически не зависят от Win32, и вы даже можете использовать SQL server или другие популярные базы данных (есть много поставщиков баз данных в комплекте с Mono).

Windows.Перенос форм иногда сложнее, потому что разработчики любят избегать песочницы .NET и P/вызывают свои мозги, чтобы настроить такие полезные вещи, как изменение скорости мигания курсора, выраженной в виде двух точек Безье, закодированных в форме BCD в wParam. Или еще какой-нибудь хлам вроде этого.

Он имеет довольно обширный охват до .NET 4.0 и даже включает в себя некоторые функции из .NET 4.5 API, но есть несколько областей, которые мы решили не реализовывать из-за того, что API устарели, создаются новые альтернативы или область слишком велика. Следующие API-интерфейсы недоступны в Mono:

  • Windows Presentation Foundation
  • Windows Workflow Foundation (ни одна из двух версий)
  • сущность Рамки
  • "дополнения" WSE1/WSE2 к стандартному стеку веб-служб

кроме того, наша реализация WCF ограничена тем, что поддерживает Silverlight.

самый простой способ проверить ваш конкретный проект-запустить Mono Migration Analyzer (MoMA). Преимущество заключается в том, что он будет уведомлять команду Mono о проблемах, которые помешают вам использовать Mono (если таковые имеются), что позволяет им приоритизировать свою работу.

Я недавно ran MoMA на дозвуке и нашел только одну проблему-странное использование нулевых типов. Это большая кодовая база, поэтому покрытие там было довольно впечатляющим.

моно активно используется в несколько коммерческих, а также продукты с открытым исходным кодом. Он используется в некоторых больших приложениях, таких как Википедия и Центр разработчиков Mozilla, и было использовано в врезанных применениях как MP3-плееры Sansa и приводит тысячи в действие опубликованного игры.

на уровне языка, компилятор Mono полностью соответствует спецификации языка C# 5.0.

на стороне рабочего стола Mono отлично работает, если вы обязуетесь использовать GTK#. окно.Реализация форм все еще немного глючит (например, TrayIcon не работает), но она прошла долгий путь. Кроме того, GTK# - это лучший инструментарий, чем Windows Forms.

на стороне паутины, Mono снабжало достаточно ASP.NET для запуска большинства сайтов отлично. Трудность здесь заключается в том, чтобы найти хост, который имеет mod_mono, установленный на apache, или сделать это самостоятельно, если у вас есть доступ к оболочке хозяин.

в любом случае, моно отлично и стабильно.

ключевые вещи, которые следует помнить при создании кросс-платформенной программы:

  • используйте GTK# вместо Windows.Формы
  • убедитесь, что правильно случае ваши имена
  • использовать Path.Separator вместо того, чтобы хардкодить "\", также использовать Environment.NewLine вместо "\n".
  • не используйте вызовы P / Invoked для Win32 API.
  • не используйте реестр Windows.

Я лично использую Моно в прайм-тайм env. Я запускаю моно-серверы, занимающиеся гигабайтами задач, связанных с обработкой данных udp/tcp, и не могу быть счастливее.

есть особенности, и одна из самых раздражающих вещей заключается в том, что вы не можете просто "построить" свои файлы msbuild из-за текущего состояния Mono:

  • MonoDevelop (IDE) имеет некоторую частичную поддержку msbuild, но в основном будет Борк на любом "реальном" build conf за пределами простого hello-world (пользовательские задачи сборки, динамические "свойства", такие как $(Solutions dir), реальная конфигурация, чтобы назвать несколько тупиков)
  • xbuild, который должно было быть моно-поставляемая-msbuild-полностью совместимая-build-система еще более ужасна, поэтому построение из командной строки на самом деле хуже, чем использование GUI, что является очень "неортодоксальным" состоянием союза для сред Linux...

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

  • компилятор получает Борк на некоторых конструкциях
  • и некоторые более продвинутые / новые классы .NET бросают в вас неожиданное дерьмо (XLinq кто-нибудь?)
  • некоторые незрелые "функции" времени выполнения (ограничение кучи 3GB на x64... WTF!)

но heaving сказал, что вообще говоря вещи начинают работать очень быстро, и решения / обходные пути в изобилии.

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

У меня были серверы, работающие с mono, обрабатывающие 300 ГБ данных в день, с тоннами P/invokes и, вообще говоря, выполняющие много работы и не спящие в течение 5-6 месяцев, даже с "кровоточащим краем" mono.

надеюсь, что это помогает.

рекомендации для принятого ответа сейчас немного устарели.

  • реализация windows forms сейчас довольно хороша. (См.Paint-Mono для порта Paint.net что является довольно сложным приложением Windows forms. Все, что требовалось, это уровень эмуляции для некоторых P-Invoke и неподдерживаемых системных вызовов).
  • путь.Объединить, а также Путь.Разделитель для объединения путей и имен файлов.
  • реестр windows это нормально, если вы используете его только для хранения и извлечения данных из ваших приложений (т. е. вы не можете получить от него никакой информации о Windows, так как это в основном реестр для моно-приложений).

Если вы хотите использовать WPF you'RR out of luck Mono в настоящее время не планирует его реализовывать.

http://www.mono-project.com/WPF

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

TL; DR-не используйте моно, если вы:

  • используйте Домены приложений (загрузка сборки\выгрузка) в многопоточных средах
  • не может поддерживать модель "дай ей провалиться"
  • опыт случайных событий большой нагрузки во время выполнения процесса

Итак, факты.

мы используем mono-2.6.7 (.net v 3.5) на RHEL5, Ubuntu, и, на мой взгляд, это самая стабильная версия, построенная Novell. У него есть проблема с выгрузкой AppDomains (segfaults), однако она терпит неудачу очень редко, и это, безусловно, приемлемо (нами).

- ладно. Но если вы хотите использовать возможности .net 4.0, вы должны переключиться на версии 2.10.x, или 3.x, и именно там начинаются проблемы.

по сравнению с 2.6.7, новые версии просто неприемлемы для использования. Я написал простое приложение для стресс-тестов для тестов моно установки.

это здесь, с инструкциями по использованию:https://github.com/head-thrash/stress_test_mono

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

результаты не очень хорошие. На самом деле, для версии 3.0.12:

  • сгэн ГК процесс падений практически сразу
  • моно с Бем живет дольше (от 2 до 5 часов), но segfaults в конечном итоге

Как упоминалось выше, sgen gc просто не работает (моно построен из источника):

* Assertion: should not be reached at sgen-scan-object.h:111

Stacktrace:


Native stacktrace:

    mono() [0x4ab0ad]
    /lib/x86_64-linux-gnu/libpthread.so.0(+0xfcb0) [0x2b61ea830cb0]
    /lib/x86_64-linux-gnu/libc.so.6(gsignal+0x35) [0x2b61eaa74425]
    /lib/x86_64-linux-gnu/libc.so.6(abort+0x17b) [0x2b61eaa77b8b]
    mono() [0x62b49d]
    mono() [0x62b5d6]
    mono() [0x5d4f84]
    mono() [0x5cb0af]
    mono() [0x5cb2cc]
    mono() [0x5cccfd]
    mono() [0x5cd944]
    mono() [0x5d12b6]
    mono(mono_gc_collect+0x28) [0x5d16f8]
    mono(mono_domain_finalize+0x7c) [0x59fb1c]
    mono() [0x596ef0]
    mono() [0x616f13]
    mono() [0x626ee0]
    /lib/x86_64-linux-gnu/libpthread.so.0(+0x7e9a) [0x2b61ea828e9a]
    /lib/x86_64-linux-gnu/libc.so.6(clone+0x6d) [0x2b61eab31ccd]

Что касается boehm segfauls-например (Ubuntu 13.04, mono построен из исходного кода):

mono: mini-amd64.c:492: amd64_patch: Assertion `0' failed.
Stacktrace:
at <unknown> <0xffffffff>
at System.Collections.Generic.Dictionary`2.Init (int,System.Collections.Generic.IEqualityComparer`1<TKey>) [0x00012] in /home/bkmz/my/mono/mcs/class/corlib/System.Collections.Generic/Dictionary.cs:264
at System.Collections.Generic.Dictionary`2..ctor () [0x00006] in /home/bkmz/my/mono/mcs/class/corlib/System.Collections.Generic/Dictionary.cs:222
at System.Security.Cryptography.CryptoConfig/CryptoHandler..ctor (System.Collections.Generic.IDictionary`2<string, System.Type>,System.Collections.Generic.IDictionary`2<string, string>) [0x00014] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/Crypto
Config.cs:582
at System.Security.Cryptography.CryptoConfig.LoadConfig (string,System.Collections.Generic.IDictionary`2<string, System.Type>,System.Collections.Generic.IDictionary`2<string, string>) [0x00013] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/CryptoCo
nfig.cs:473
at System.Security.Cryptography.CryptoConfig.Initialize () [0x00697] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:457
at System.Security.Cryptography.CryptoConfig.CreateFromName (string,object[]) [0x00027] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:495
at System.Security.Cryptography.CryptoConfig.CreateFromName (string) [0x00000] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:484
at System.Security.Cryptography.RandomNumberGenerator.Create (string) [0x00000] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs:59
at System.Security.Cryptography.RandomNumberGenerator.Create () [0x00000] in /home/bkmz/my/mono/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs:53
at System.Guid.NewGuid () [0x0001e] in /home/bkmz/my/mono/mcs/class/corlib/System/Guid.cs:492

или (RHEL5, моно берется из rpm здесь ftp://ftp.pbone.net/mirror/ftp5.gwdg.de/pub/opensuse/repositories/home%3A/vmas%3A/mono-centos5)

Assertion at mini.c:3783, condition `code' not met
Stacktrace:
at <unknown> <0xffffffff>
at System.IO.StreamReader.ReadBuffer () [0x00012] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.IO/StreamReader.cs:394
at System.IO.StreamReader.Peek () [0x00006] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.IO/StreamReader.cs:429
at Mono.Xml.SmallXmlParser.Peek () [0x00000] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/Mono.Xml/SmallXmlParser.cs:271
at Mono.Xml.SmallXmlParser.Parse (System.IO.TextReader,Mono.Xml.SmallXmlParser/IContentHandler) [0x00020] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/Mono.Xml/SmallXmlParser.cs:346
at System.Security.Cryptography.CryptoConfig.LoadConfig (string,System.Collections.Generic.IDictionary`2<string, System.Type>,System.Collections.Generic.IDictionary`2<string, string>) [0x00021] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptog
raphy/CryptoConfig.cs:475
at System.Security.Cryptography.CryptoConfig.Initialize () [0x00697] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:457
at System.Security.Cryptography.CryptoConfig.CreateFromName (string,object[]) [0x00027] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:495
at System.Security.Cryptography.CryptoConfig.CreateFromName (string) [0x00000] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptography/CryptoConfig.cs:484
at System.Security.Cryptography.RandomNumberGenerator.Create (string) [0x00000] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs:59
at System.Security.Cryptography.RandomNumberGenerator.Create () [0x00000] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Security.Cryptography/RandomNumberGenerator.cs:53
at System.Guid.NewGuid () [0x0001e] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System/Guid.cs:483
at System.Runtime.Remoting.RemotingServices.NewUri () [0x00020] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs:356
at System.Runtime.Remoting.RemotingServices.Marshal (System.MarshalByRefObject,string,System.Type) [0x000ba] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs:329
at System.AppDomain.GetMarshalledDomainObjRef () [0x00000] in /usr/src/redhat/BUILD/mono-3.0.3/mcs/class/corlib/System/AppDomain.cs:1363

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

кстати, тестируемая программа работала 24 часа на машине Windows в MS .NET 4.5 env без каких-либо сбоев.

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

MoMA-отличный инструмент для этого, как кто-то еще предложил. Самыми большими источниками несовместимости в наши дни являются приложения, которые DllImport (или P / Invoke) в библиотеки Win32. Некоторые сборки не реализованы, но большинство из них только для Windows и не имеет смысла на Linux. Я думаю, что это довольно безопасно сказать, что большинство ASP.NET приложения могут работать на моно с ограниченными модификациями.

(раскрытие информации: я внес свой вклад в моно себя, а также письменные приложения это работает поверх него.)

во многих случаях вы можете взять существующий код и просто запустить его на Mono, особенно если вы портируете ASP.NET применение.

в некоторых случаях вам могут потребоваться целые новые разделы кода, чтобы заставить его работать. Если вы используете систему.Окна.Форм, например, приложение не будет работать без изменений. Аналогично, если вы используете какой-либо код для Windows (например, код доступа к реестру). Но я думаю, что худший преступник-это код пользовательского интерфейса. Это особенно плохо на системах Macintosh.

мы использовали его для проекта здесь на работе, который должен был работать на Linux, но повторно использовать некоторые библиотеки .NET, которые мы построили в управляемом C++. Я был очень удивлен тем, насколько хорошо это сработало. Наш основной исполняемый файл написан на C#, и мы можем просто ссылаться на наши управляемые двоичные файлы C++ без проблем. Единственное различие в коде C# между Windows и Linux-это код последовательного порта RS232.

единственная большая проблема, о которой я могу думать, произошла около месяца назад. Сборка Linux была утечка памяти, которая не была замечена на сборке Windows. После выполнения некоторой ручной отладки (основные профилировщики для Mono на Linux не очень помогли), мы смогли сузить проблему до определенного куска кода. Мы закончили тем, что исправили обходной путь, но мне все еще нужно найти время, чтобы вернуться и выяснить, в чем была основная причина утечки.

знаете ли вы, насколько хороша поддержка Mono 2.0 preview для Windows Forms 2.0?

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

Да, это определенно (если вы будете осторожны, хотя) Мы поддерживаем Mono в Ra-Ajax (библиотека Ajax находится по адресуhttp://ra-ajax.org) и у нас в основном вообще нет проблем. Вам нужно быть осторожным с некоторыми из "самых безумных вещей" из .Net, таких как WSE и т. д., а также, вероятно, некоторые из ваших существующих проектов не будут на 100% совместимы с моно, но новые проекты, если вы их тестируете во время разработки, в основном будут совместимы без проблем с моно. И выгода от этого поддержка Linux и т. д. С помощью Mono действительно круто ;)

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

для типа приложения, которое мы создаем Mono, к сожалению, не кажется готовым к производству. Мы были впечатлены им в целом, и впечатлены его производительностью как на Windows, так и на машинах EC2, однако наша программа разбилась последовательно с ошибками сборки мусора как на Windows, так и на linux.

сообщение об ошибке: "фатальные ошибки в GC: слишком много разделов кучи", вот ссылка на кого-то другого, испытывающего проблему в немного другом образом:

http://bugzilla.novell.com/show_bug.cgi?id=435906

первый фрагмент кода, который мы запустили в Mono, был простой задачей программирования, которую мы разработали... Код загружает около 10 МБ данных в некоторые структуры данных (например, хэш-наборы), а затем выполняет 10 запросов к данным. Мы выполнили запросы 100 раз, чтобы рассчитать их и получить среднее значение.

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

этот код очень прост, например, поместите некоторые данные в хэш-наборы, а затем запросите эти хэш-наборы и т. д., Все собственные c#, ничего небезопасного, никаких вызовов API. На Microsoft CLR он никогда не падает и работает на огромных наборах данных 1000 раз просто отлично.

один из наших парней отправил Мигелю по электронной почте и включил код, который вызвал проблему, пока нет ответа. : (

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

просто проверьте www.plasticscm.com все (клиент, сервер, GUI, инструменты слияния) написано на mono.

Это действительно зависит от пространств имен и классов, которые вы используете из .NET framework. У меня был интерес к преобразованию одной из моих служб windows для запуска на моем почтовом сервере, который является Suse, но мы столкнулись с несколькими жесткими блокировками с API, которые не были полностью реализованы. Где-то на веб-сайте Mono есть диаграмма, в которой перечислены все классы и их уровень завершения. Если ваша заявка покрыта, то идите на это.

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

еще одна проблема, с которой мы столкнулись, - Это лицензионное программное обеспечение: если вы ссылаетесь на чужую DLL, вы не можете кодировать свой путь вокруг несовместимостей, которые похоронены в этой сборке.

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

Пример:http://community.devexpress.com/forums/p/55085/185853.aspx

нет, моно не готов к серьезной работе. Я написал несколько программ на Windows с помощью F# и запустил их на Mono. Эти программы использовали диск, память и процессор довольно интенсивно. Я видел сбои в моно библиотеках (управляемый код), сбои в машинном коде и сбои в виртуальной машине. Когда mono работал, программы были по крайней мере в два раза медленнее, чем в .Net в Windows, и использовали гораздо больше памяти. Держитесь подальше от моно для серьезной работы.