-6

製品のコマンド ライン オプションを処理するために使用する抽象クラスを作成しました。

AbstractOptions から継承するクラスを作成し、装飾されたフィールドを入力して、継承された Parse(args) メソッドを呼び出すだけで、リフレクションによってコマンド ラインからの値が自動的に入力されます。コマンド ラインで見つからなかった値は、現在の (デフォルト) 値を保持します。

その後、アプリケーションはオプション フィールドをチェックして値を取得するだけで済みます。AbstractOptions クラスは、ヘルプ出力など、より多くの機能を提供しますが、それは重要ではありません。

短い例:

public class SignalOptions: AbstractOptions
{
    [Option("-i, --iterations", "Number of iterations (0 = infinite).")]
    volatile public int NumberOfIterations;

    [Option("-s, --silent", "Silent mode, only display final results.")]
    volatile public bool Silent;

    [Option("-w, --zwindow", "Window size for z-score analysis.")]
    volatile public int ZWindow = 7;

    [Option("-a, --zalert", "z-score value to consider as peak.")]
    public double ZAlert = 2.1;
}

static void Main(string[] args)
{
    var opts = new SignalOptions();
    opts.Parse(args)

    // If optimizations are turned off, SILENT will be written or not 
    // followind presence or absence of the --silent switch on the command line.
    // If optimizations are turned on, SILENT will never be written.
    // The reflection part is working fine. I suspect the problem is that
    // the compiler of the jitter having never found this set anywhere simply inlines
    // the value 'false' inthe if, because when I step on it, it shows me the value as 
    // true or false, but has the same behavior no matter what value opts.Silence has.
    if( opts.Silent )
        Console.Writeline("SILENT");
}       

さて、私が抱えている問題は、コンパイラが SignalOptions クラスの値を実際に変更するコードを見つけられないため、コードで使用されている値を単にインライン化することです。クラスのすべての「オプション」フィールドが揮発性であることを要求することで問題を回避したため、最適化は適用されず、正常に動作しますが、残念ながら揮発性キーワードは double では無効です。

回避策を見つけるためにネットで多くの時間を費やしましたが、成功しませんでした。フィールドの最適化を防ぐか、コンパイラ/ジッターをだまして実行時に使用されていると思わせる方法はありますか?

また、呼び出し元のアプリケーションの負担をできるだけ少なくしたいと考えています。

ありがとう

4

2 に答える 2

1

Parse私はここにかなり不透明なものとして書かれたローカルコピーを持っています:

public void Parse(string[] args)
{    // deliberately opaque, not that it would make any difference
    string fieldName = (new string('S', 1) + "ilentX").Substring(0, 6);
    GetType().GetField(fieldName).SetValue(this, true);
}

正常に動作します。問題はあなたが思っていることだとは思いません。

于 2012-04-24T07:00:03.493 に答える
1

これが私の推測です:

Parse別のスレッドで実行されていますが、同期に何らかの欠陥があるため、値が設定されていなくても残りのコードが実行されます。

これにより、デバッガーで正しい値が表示される理由も説明されます。

更新(意見あり):

別のスレッドParseで実行することは非常に奇妙であり、設計上の欠陥と見なす必要があります。誰かが「反映が遅い、別のスレッドに入れよう」と考えていたようです。

于 2012-04-24T07:20:58.003 に答える