大規模または中規模のプロジェクトでオープンソースの.NET実装であるMonoを使用した人はいますか?実世界の実稼働環境に対応できるかどうか疑問に思っています。それは安定していて、速くて、互換性がありますか...使用するのに十分ですか?プロジェクトをMonoランタイムに移植するのに多大な労力を要しますか、それとも、Microsoftのランタイム用に既に記述されたコードを取得して実行するのに十分な互換性が本当にありますか?
17 に答える
考慮すべきシナリオが 2 つあります。(b) 新しいコードを書き始めており、Mono が十分に成熟しているかどうかを知りたい場合。
最初のケースでは、Mono Migration Analyzer ツール(Moma) を使用して、アプリケーションが Mono で実行されるまでの距離を評価できます。評価結果が明快に返ってきた場合は、テストと QA に着手し、出荷の準備を整える必要があります。
Mono のセマンティクスが欠落している、またはセマンティクスが大きく異なる機能を強調するレポートで評価が返された場合は、コードを適合させたり、書き直したりできるかどうか、または最悪の場合、アプリケーションが機能を減らして動作できるかどうかを評価する必要があります。
ユーザーの投稿に基づく Moma の統計 (これは記憶によるものです) によると、アプリケーションの約 50% はすぐに使用でき、約 25% は約 1 週間分の作業 (リファクタリング、適応) が必要です。コードのチャンクをやり直しても、残りは Win32 と信じられないほど結びついているため、わざわざ移植する価値はありません。その時点で、ゼロから始めるか、ビジネス上の決定によってコードを移植可能にする努力が必要になりますが、(少なくとも私たちが持っているレポートによると) 何ヶ月にもわたる作業について話していることになります。
ゼロから始める場合は、Mono に存在する API のみを使用するため、状況ははるかに単純です。サポートされているスタック (ほぼ .NET 2.0 に加えて、LINQ や System.Core を含む 3.5 のすべてのコア アップグレード、および Mono クロスプラットフォーム API のいずれか) を使用している限り、問題はありません。
時々、Mono のバグや制限に遭遇し、それらを回避する必要があるかもしれませんが、それは他のシステムと同じです。
移植性について: ASP.NET アプリケーションは、Win32 との依存関係がほとんどまたはまったくなく、SQL サーバーやその他の一般的なデータベースを使用することもできるため、移植が容易なアプリケーションです (Mono には多数のデータベース プロバイダーがバンドルされています)。
Windows.Forms の移植は、開発者が .NET サンドボックスをエスケープし、wParam で BCD 形式でエンコードされた 2 つのベジエ ポイントとして表されるカーソルの点滅速度を変更するのと同じくらい便利なことを P/Invoke で構成することを好むため、よりトリッキーな場合があります。またはそのようないくつかのがらくた。
.NET 4.0まではかなり広範囲にカバーされており、.NET 4.5 APIの一部の機能も含まれていますが、APIが非推奨になったり、新しい代替案が作成されたり、スコープが多すぎたりするため、実装しないことを選択した領域がいくつかあります。大きい。次のAPIはMonoでは使用できません。
- Windows Presentation Foundation
- Windows Workflow Foundation(2つのバージョンのどちらでもない)
- エンティティフレームワーク
- 標準のWebサービススタックへのWSE1/WSE2「アドオン」
さらに、WCFの実装は、Silverlightがサポートするものに限定されています。
特定のプロジェクトを確認する最も簡単な方法は、Mono Migration Analyzer(MoMA)を実行することです。利点は、Monoチームに問題を通知することです。これにより、Mono(存在する場合)を使用できなくなり、作業に優先順位を付けることができます。
私は最近SubSonicでMoMAを実行しましたが、問題が1つだけ見つかりました。それはNullable型の奇妙な使用法です。それは大きなコードベースなので、そこでの報道はかなり印象的でした。
Monoは、いくつかの商用製品およびオープンソース製品で積極的に使用されています。ウィキペディアやMozillaDeveloperCenterなどの一部の大規模なアプリケーションで使用されており、Sansa MP3プレーヤーなどの組み込みアプリケーションで使用されており、公開されている何千ものゲームに電力を供給しています。
デスクトップ側では、GTK#の使用を確約すると、Monoはうまく機能します。Windows.Formsの実装はまだ少しバグがありますが(たとえば、TrayIconは機能しません)、長い道のりを歩んできました。その上、GTK#はそのままWindowsフォームよりも優れたツールキットです。
Web側では、Monoはほとんどのサイトを完全に実行するのに十分なASP.NETを実装しています。ここでの難しさは、Apacheにmod_monoがインストールされているホストを見つけること、またはホストへのシェルアクセスがある場合は自分でそれを行うことです。
いずれにせよ、Monoは素晴らしく、安定しています。
クロスプラットフォームプログラムを作成するときに覚えておくべき重要なこと:
- Windows.Formsの代わりにGTK#を使用する
- ファイル名を正しく大文字にするようにしてください
Path.Separator
ハードコーディングの代わりに使用し、の代わり"\"
にも使用します。Environment.NewLine
"\n"
- Win32APIへのP/Invoked呼び出しは使用しないでください。
- Windowsレジストリを使用しないでください。
私は個人的にプライムタイムの環境でMonoを使用しています。私はギガバイトのudp/tcpデータ処理関連のタスクを処理するモノラルサーバーを実行していますが、これ以上幸せなことはありません。
特殊性があり、最も厄介なことの1つは、Monoの現在の状態が原因で、msbuildファイルを単に「ビルド」できないことです。
- MonoDevelop(IDE)には部分的なmsbuildサポートがありますが、基本的には、単純なhello-world(カスタムビルドタスク、$(SolutionDir)などの動的な「プロパティ」、いくつかのデッドを挙げた実際の構成)を超えた「REAL」ビルドconfに影響を与えます。 -終了)
- モノサプライのmsbuild-fully-compatible-build-systemである必要があるxbuildはさらにひどいので、コマンドラインからのビルドは実際にはGUIを使用するよりも悪い経験です。これは非常に「非正統的な」状態です。 Linux環境のユニオン...
一度/あなたのものを実際に構築する間に、あなたは次のようにサポートされるべきであるコードのためにさえいくつかの荒野を見るかもしれません:
- コンパイラが特定の構造で中断される
- そして、あなたに予期しないがらくたを投げる特定のより高度な/新しい.NETクラス(XLinq誰か?)
- いくつかの未熟なランタイム「機能」(x64で3GBのヒープ制限... WTF!)
しかし、Heavingは、一般的に言えば、物事は非常に迅速に機能し始め、解決策/回避策は豊富であると述べました。
あなたがそれらの最初のハードルを乗り越えたら、私の経験はそのモノロックであり、すべての反復で良くなり続けます。
私はサーバーをモノラルで実行し、1日あたり300GBのデータを処理し、大量のp /呼び出しを行い、一般的に言って、「最先端」のモノラルを使用しても、多くの作業を行い、5〜6か月間稼働し続けています。
お役に立てれば。
受け入れられた回答の推奨事項は、現在は少し古くなっています。
- 現在、Windows フォームの実装はかなり良好です。(かなり複雑な Windows フォーム アプリケーションである Paint.net のポートについては、 Paint-Monoを参照してください。必要だったのは、いくつかの P-Invoke およびサポートされていないシステム コールのエミュレーション レイヤーだけでした)。
- Path.Combine と Path.Seperator を使用して、パスとファイル名を結合します。
- Windows レジストリは、アプリケーションからデータを保存および取得するためだけに使用する限り問題ありません (つまり、基本的に Mono アプリケーションのレジストリであるため、そこから Windows に関する情報を取得することはできません)。
WPF を使用したい場合は、運が悪いです。Mono は現在、WPF を実装する予定はありません。
そうですね、モノはいいんですが、私が見る限り、不安定です。動作しますが、モノプロセスに深刻な作業をさせると失敗します。
TL;DR - 次の場合はモノを使用しないでください。
- マルチスレッド環境で AppDomains (Assembly Load\Unload) を使用する
- 「失敗は許す」モデルを維持できない
- プロセスの実行中に時々高負荷イベントが発生する
だから、事実。
RHEL5、Ubuntu で mono-2.6.7 (.net v 3.5) を使用しています。私の見解では、Novell によって構築された最も安定したバージョンです。AppDomains のアンロード (segfaults) に問題がありますが、非常にまれに失敗するため、これは (私たちには) 許容範囲内です。
わかった。しかし、.net 4.0 の機能を使用したい場合は、バージョン 2.10.x または 3.x に切り替える必要があり、そこから問題が発生します。
2.6.7 と比較すると、新しいバージョンはまったく使用できません。mono インストールをテストするための簡単なストレス テスト アプリケーションを作成しました。
ここに、使用方法が記載されています: https://github.com/head-thrash/stress_test_mono
スレッド プール ワーカー スレッドを使用します。ワーカーは dll を AppDomain にロードし、数学的な作業を試みます。作業の一部はマルチスレッドで、一部は単一です。ディスクからのファイルの読み取りがいくつかありますが、ほとんどすべての作業は CPU バウンドです。
結果はあまり良くありません。実際、バージョン 3.0.12 の場合:
- sgen GC segfaults はほぼ即時に処理されます
- boehm を使用した mono の寿命は長くなりますが (2 時間から 5 時間)、最終的にセグメンテーション違反が発生します
上記のように、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: 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、mono はここで 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 ではそれらに近づかないようにする必要があります。
ところで、テストされたプログラムは、MS .NET 4.5 env の Windows マシンで 24 時間問題なく動作しました。
結論として、モノを慎重に使用してください。一見すると機能しますが、いつでも簡単に失敗する可能性があります。大量のコア ダンプが残され、オープンソース プロジェクトへの大きな信頼が失われます。
他の誰かが示唆したように、MoMA はこれに最適なツールです。最近の非互換性の最大の原因は、Win32 ライブラリに DllImport (または P/Invoke) するアプリケーションです。一部のアセンブリは実装されていませんが、それらのほとんどは Windows 専用であり、Linux では意味がありません。ほとんどの ASP.NET アプリケーションは、限られた変更で Mono 上で実行できると言っても過言ではありません。
(開示: 私は Mono 自体に貢献し、その上で実行されるアプリを作成しました。)
多くの場合、特にASP.NETアプリケーションを移植する場合は、既存のコードを取得してMonoで実行することができます。
場合によっては、それを機能させるためにコードのまったく新しいセクションが必要になることがあります。たとえば、System.Windows.Formsを使用する場合、アプリケーションは変更せずに動作しません。同様に、Windows固有のコード(レジストリアクセスコードなど)を使用する場合。しかし、最悪の犯罪者はUIコードだと思います。これはMacintoshシステムでは特に悪いことです。
Linux で実行する必要があるが、マネージド C++ で構築したいくつかの .NET ライブラリを再利用する必要があるプロジェクトに使用しています。私はそれがどれほどうまくいったかに非常に驚いています. メインの実行可能ファイルは C# で記述されており、Managed C++ バイナリを問題なく参照できます。Windows と Linux の C# コードの唯一の違いは、RS232 シリアル ポート コードです。
私が考えることができる唯一の大きな問題は、約1か月前に発生しました。Linux ビルドには、Windows ビルドでは見られなかったメモリ リークがありました。手動でデバッグを行った後 (Linux 上の Mono の基本的なプロファイラーはあまり役に立ちませんでした)、問題を特定のコード チャンクに絞り込むことができました。最終的には回避策にパッチを当てることになりましたが、戻ってリークの根本原因が何であったかを突き止めるための時間を見つける必要があります.
Windowsフォーム2.0に対するMono2.0プレビューのサポートがどれほど優れているか知っていますか?
私がそれで遊んだ少しから、それは比較的完全でほとんど使用可能であるように見えました。一部の場所では見栄えがよくなく、全体的にはまだ少しヒットまたはミスしています。正直なところ、いくつかのフォームと同じように機能することに驚きました。
私たちが構築しているタイプのアプリケーションについては、残念ながら、Mono は製品化の準備ができていないようです。私たちは全体的に感銘を受け、Windows と EC2 マシンの両方でのパフォーマンスに感銘を受けましたが、プログラムは Windows と Linux の両方で一貫してガベージ コレクション エラーでクラッシュしました。
エラー メッセージは次のとおりです。
http://bugzilla.novell.com/show_bug.cgi?id=435906
Mono で実行した最初のコードは、私たちが開発した単純なプログラミングの課題でした...コードは、約 10MB のデータをいくつかのデータ構造 (HashSets など) にロードし、データに対して 10 個のクエリを実行します。時間を計って平均を得るために、クエリを 100 回実行しました。
Windows では、55 番目のクエリのあたりでコードがクラッシュしました。Linux では機能しましたが、より大きなデータ セットに移動するとすぐに、クラッシュすることもありました。
このコードは非常に単純です。たとえば、いくつかのデータを HashSets に入れ、それらの HashSets などをクエリします。すべてネイティブ C# であり、危険なものはなく、API 呼び出しもありません。Microsoft CLR ではクラッシュすることはなく、膨大なデータ セットで数千回問題なく実行されます。
私たちの担当者の 1 人が Miguel に電子メールを送信し、問題の原因となったコードを含めましたが、まだ応答はありません。:(
また、他の多くの人が解決策なしでこの問題に遭遇したようです.Monoを別のGC設定で再コンパイルする解決策が提案されていますが、それはクラッシュする前にしきい値を上げるようです.
はい、間違いなくそうです (気を付ければ) 私たちは Ra-Ajax (Ajax ライブラリはhttp://ra-ajax.orgにあります) で Mono をサポートしており、ほとんど問題はありません。WSE などの .Net の「非常識なもの」には注意が必要です。また、おそらく既存のプロジェクトのかなりの数は 100% Mono 互換ではありませんが、開発中にテストすると、新しいプロジェクトはほとんどMono と問題なく互換性があります。そして、Mono を使用して Linux などをサポートすることで得られるメリットは本当に素晴らしいです ;)
Mono をサポートする秘訣の大部分は、ActiveRecord、log4net、ra-ajax などの適切なツールを最初から使用することだと思います。
www.plasticscm.comをチェックしてください。すべて (クライアント、サーバー、GUI、マージ ツール) は mono で書かれています。
これは、.NETFrameworkから使用している名前空間とクラスによって異なります。Windowsサービスの1つをEメールサーバーで実行するように変換することに興味がありました。それはSuseですが、完全に実装されていないAPIでいくつかの困難な障害に遭遇しました。MonoのWebサイトのどこかに、すべてのクラスとその完了レベルをリストしたチャートがあります。アプリケーションがカバーされている場合は、それを選択してください。
もちろん、他のアプリケーションと同様に、完全にコミットする前にプロトタイピングとテストを行ってください。
私たちが遭遇したもう1つの問題は、ライセンスされたソフトウェアです。他の誰かのDLLを参照している場合、そのアセンブリに埋もれている非互換性を回避する方法をコーディングすることはできません。
サードパーティのコンポーネントを含むアプリケーションがある場合は、詰め込まれている可能性があります。多くのベンダーがMonoを念頭に置いて開発するのではないかと思います
例:http ://community.devexpress.com/forums/p/55085/185853.aspx
いいえ、モノは本格的な作業の準備ができていません。F# を使用して Windows でいくつかのプログラムを作成し、Mono で実行しました。これらのプログラムは、ディスク、メモリ、および CPU をかなり集中的に使用しました。mono ライブラリ (マネージ コード) でのクラッシュ、ネイティブ コードでのクラッシュ、仮想マシンでのクラッシュが見られました。mono が機能すると、プログラムは Windows の .Net よりも少なくとも 2 倍遅くなり、より多くのメモリを使用しました。真剣な仕事のためにモノから離れてください。