17

MSDNによると、WindowsサービスまたはASP.NETサービスのSystem.Drawing名前空間内でクラスを使用することは特に良い考えではありません。現在、この特定の名前空間(フォントを測定するため)にアクセスする必要があるクラスライブラリを開発していますが、ホストプロセスがサービスではないことを保証することはできません。

System.Drawingが利用できない場合にフォールバックできる最適ではないメソッドがありますが、可能であれば、System.Drawingのクラスを使用したいと思います。したがって、私がやりたいのは、System.Drawingが安全かどうかをruntumeで判断し、安全である場合はそれを使用し、そうでない場合は次善のオプションにフォールバックすることです。

私の問題は、System.Drawingが安全に使用できるかどうかをどうやって検出できるかということです。

私はどちらかをすべきだと思います

  • 現在のプロセスがWindowsサービスかASP.NETサービスかを検出します
  • GDIが利用可能かどうかを検出する
  • または、System.Drawing.dll自体に安全に使用できるかどうかを確認する方法があるかもしれません。

残念ながら、私はこれらのアプローチのいずれかを実装する方法を思い付くことができません。誰かが何か考えを持っていますか?

4

5 に答える 5

19

混乱を避けるために、System.Drawing はASP.NET およびサービスの下で動作しますが、サポートされていません。高負荷 (管理されていないリソースの不足)、メモリまたはリソースのリーク (適切に実装されていない、または破棄パターンと呼ばれる)、および/または表示するデスクトップがないときにダイアログがポップされるという問題が発生する可能性があります。

テストは後者を処理し、監視は前者を警告します。ただし、問題が発生した場合は、PSS に電話して修正を依頼できるとは思わないでください。

それで、あなたのオプションは何ですか?完全にサポートされたルートが必要なく、極端な負荷が予想されない場合は、多くの人が MSDN の警告を無視して System.Drawing を使用して成功しています。それらのいくつかは噛まれましたが、失敗談よりも多くの成功談があります.

何かをサポートしたい場合は、インタラクティブに実行しているかどうかを知る必要があります。個人的には、非インタラクティブなフラグをどこかに設定するのは、おそらくホスティング アプリに任せるでしょう。結局のところ、アプリは、ホストされた環境にあるかどうか、および/または GDI+ の問題を危険にさらしたいかどうかを判断するのに最適な位置にあります。

しかし、環境を自動的に検出したい場合は、SOでサービスのためにここで提供されるよりも悪い答えがあると思います。要約すると、EntryAssembly をチェックして ServiceBase から継承されているかどうかを確認するか、System.Console にアクセスしてみてください。ASP.NET の場合も同様に、HttpContext.Current を検出するだけで十分です。

私はデスクトップを探すための管理された方法または p/invoke の方法があると思います (これは本当にこれらすべての決定的な要因だと思います) および/または AppDomain からあなたの手がかりになる何か. しかし、私は '私はそれが何であるかわからず、MSDN はそれについて啓発的ではありません。

編集: MSDN をトローリングして、ここで重要なのは実際には (デスクトップをホストする) Window Stationであることを思い出しました。その情報を使用して、現在のウィンドウ ステーションへのハンドルを返すGetProcessWindowStation()を見つけることができました。そのハンドルをGetUserObjectInformation()に渡すと、デスクトップが表示されている場合、WSF_VISIBLE を持つ dwFlags を持つ必要があるUSEROBJECTFLAGS構造体が取得されます。

または、EnumWindowsStationsを使用すると、確認できるステーションのリストが表示されます。WinSta0 はインタラクティブなステーションです。

しかし、ええ、私はまだアプリにプロパティなどを設定させる方がはるかに簡単だと思います....

再度編集: 7 年後、MSが上で説明した正確な GetProcessWindowStation ダンスを実行するEnvironment.UserInteractiveに手がかりを得る..ホスティング アプリに委任することをお勧めします (彼らはもっと速くしたいかもしれませんが、少しだけ)よりリスクの高い System.Drawing パス) ですが、UserInteractive は、自分でピンボークせずに使用するのに適したデフォルトのようです。

于 2008-12-24T02:27:46.777 に答える
4

公式にはサポートされていませんが、パフォーマンスや信頼性の問題を引き起こすことなく、大量のWebサーバー(WebアプリケーションとWebサービスの両方)でSystem.Drawingクラスを何年にもわたって使用してきました。

コードが安全に使用できるかどうかを判断する唯一の方法は、using {}ステートメントでオブジェクトをテスト、監視、および外部リソースでラップすることだと思います。

于 2010-06-18T18:34:02.777 に答える
1

代わりにTextRendererを使用できます。ASP.NETでSystem.Windows.Formsから何かを使用するのは奇妙なことですが、ASP.NETでサポートされていないという同じ警告は表示されません。私はTextRendererとGraphics.MeasureStringの両方を使用してASP.NETアプリケーションの文字列を測定したので、両方とも機能します。System.DrawingがASP.NETで推奨されないという警告を見たことがありませんでした。

TextRendererは、Graphics.MeasureString、FWIWよりもはるかに低速です。

于 2008-12-24T01:10:18.163 に答える
0

これは、STAスレッドを必要とするGDIサブシステムと関係がある可能性があります。この場合は、関連するaspxページの@PAGEディレクティブでASPCOMPAT=TRUEを指定することを検討してください。これにより、aspxページがSTAスレッドIIRCで実行されます。

-オシーン

于 2008-12-24T01:19:18.333 に答える
-1

System.Drawing.dllをアプリケーションのbinにコピーして、そのように使用できる場合があります。それはその可用性を保証するかもしれません。

アプリケーションの参照を右クリックして、[ローカルコピー]のオプションをtrueに変更します。

私は質問を誤解しているかもしれませんが...

于 2008-12-24T01:16:13.020 に答える