2017-11-26 5 views
0

私はqueeクラスと静的なrefrencesを使用して問題があります。私は、静的および複数のスレッドが問題をcuasingことを知っている静的クラス論理を変更する方法オブジェクト参照はオブジェクトの問題の設定をしないでください。

protected static Queue reportQueue = new Queue(); 

protected static ReportDocument CreateReport(Type reportClass) 
{ 
    object report = Activator.CreateInstance(reportClass); 
    reportQueue.Enqueue(report); 
    return (ReportDocument)report; 
} 

public static ReportDocument GetReport(Type reportClass) 
{ 
    int maxPrintLimit = Convert.ToInt32(ConfigurationManager.AppSettings["MaxPrintLimit"].ToString()); 
    //75 is my print job limit. 
    if (reportQueue.Count > maxPrintLimit) ((ReportDocument)reportQueue.Dequeue()).Dispose(); 
    return CreateReport(reportClass); 
} 

は、ここに私のコードです。

たとえば、静的メソッドがあり、その内部に静的フィールドがある場合などです。マルチスレッドでは、あるスレッドがプロパティ値を変更すると、別のスレッドが同じproprtyを使用する可能性があります。最初のthredがnullに設定した場合、その時点でrefrenceオブジェクトからオブジェクトが発生する可能性があります。

私のコードは、このコードを実行しているオブジェクトのインスタンスにオブジェクト参照を設定しないため、この問題を経験しますか?

どのように解決できますか?

staticを削除すると機能しますか?

どのような提案も役立ちます。

おかげ

+1

あなたは、同時に何かをした場合、あなたはそれが問題を引き起こすことはありませんを確認する必要があります。静的または非静的では違いはありません。並行データ構造またはロックを使用する必要があります。 –

+0

@SamKuhmonenありがとう、これは以前の開発者コードですが、彼は工場のパターンを使用しようとしていたと思いますが、間違った方法でコードを変更して感謝をチェックします。 – user123456

+0

'ConcurrentQueue'を使用してください。 – mjwills

答えて

0

私はこれに私のコードを更新:

protected static ConcurrentQueue<object> reportQueue = ConcurrentQueue<object(); 

    protected static ReportDocument CreateReport(Type reportClass) 
    { 
     object report = Activator.CreateInstance(reportClass); 
     reportQueue.Enqueue(report); 
     return (ReportDocument)report; 
    } 

    public static ReportDocument GetReport(Type reportClass) 
    { 
     int maxPrintLimit = Convert.ToInt32(ConfigurationManager.AppSettings["MaxPrintLimit"].ToString()); 
     //75 is my print job limit. 
     if (reportQueue.Count > maxPrintLimit) 
     { 
      object obj; 
      if (reportQueue.TryDequeue(out obj)) 
      { 
       ((ReportDocument)obj).Dispose(); 
      } 
     } 
     return CreateReport(reportClass); 
    } 
+0

スレッドセーフです。 'Count'の使用は' Queue'よりも遅くなることに注意してください。また、 'Count'と' maxPrintLimit'を比較すると競合状態になり、複数のスレッドが同時にそのチェックに当たった場合(キューには26個のアイテムがあります)、TryDequeueとなり、74個のアイテムになります75)。さらに、 'ConcurrentQueue 'の代わりに 'ConcurrentQueue 'を使いたいと思うでしょう。代わりに、 'BoundedCapacity' setで' BlockingCollection'を使うことも考えてみましょう - https://docs.microsoft.com/en-us/dotnet/standard/collections/thread-safe/blockingcollection-overview。 – mjwills

+0

@mjwills。あなたの答えをありがとう、私は後でアクションにその配慮を取るが、今私の問題を解決させてください、私のエンドユーザーは、この時点でレポートを印刷することはできません。私はそれをオブジェクトにしました。なぜなら、このメソッドをCreateInstanceにして、他のオブジェクトを返すということです。これは、レポートドキュメントを使用すると、Activator.CreateInstance(reportClass); – user123456

+0

'' ReportDocument'しか格納していないのであれば、それを汎用化したいのでオブジェクト化しました。 – mjwills

関連する問題