2

VS2008単体テストプロジェクトでTraceSource.TraceDataを呼び出そうとすると、ObjectDisposedExceptionが発生します。以下に、問題を一貫して再現する非常に小さなコードサンプルを含めました。これは、最初の単体テストを実行した後にのみ表示されますが、Webサイトが起動して多くのユーザーで実行されると、影響を受ける可能性があります。

これは、最初の単体テストの後で、基になるストリームが閉じられているようなものです。「オーバーフロー」の達人からの助けを大いに歓迎します。

手順:

1)VS2008単体テストプロジェクトを作成します

2)次のコードでクラスを追加します。

namespace TracingError
{
    using System.Diagnostics;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class UnitTest1
    {
        public static TraceSource ts = new TraceSource("TraceTest");

        [TestMethod]
        public void A()
        {
            ts.TraceEvent(TraceEventType.Information, 1, "Hello from A");
        }

        [TestMethod]
        public void B()
        {
            ts.TraceEvent(TraceEventType.Information, 1, "Hello from B");
        }
    }
}

3)次のコードでapp.configを追加します。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <sources>
      <source name="TraceTest" switchName="SourceSwitch" switchType="System.Diagnostics.SourceSwitch">
        <listeners>
          <add name="console" type="System.Diagnostics.ConsoleTraceListener" initializeData="false" />
          <remove name="Default" />
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="SourceSwitch" value="Verbose" />
    </switches>
    <trace autoflush="true" indentsize="4"></trace>
  </system.diagnostics>
</configuration>
4

1 に答える 1

3

Trace.WriteLine呼び出しを使用してコードを実行するテストを実行したときに、同じ問題が発生しました。単一のテストを実行することは問題ありませんが、複数を実行すると、次の呼び出しスタックがトリガーされます。

System.IO.__Error.WriterClosed()
System.IO.StringWriter.Write(Char[] buffer, Int32 index, Int32 count)
System.IO.TextWriter.WriteLine(String value)
System.IO.TextWriter.SyncTextWriter.WriteLine(String value)
System.Diagnostics.TextWriterTraceListener.WriteLine(String message)
System.Diagnostics.TraceInternal.WriteLine(String message)
System.Diagnostics.Trace.WriteLine(String message)

調査の結果、テストセットアップに次のコードを配置することで問題を回避できることがわかりました。

[TestInitialize()]
public void Setup()
{
    Array.ForEach((from TraceListener tl in Trace.Listeners
                   where tl.Name != "Default"
                   select tl).ToArray(),
                   tl => Trace.Listeners.Remove(tl));

} 

どうやら、mstest環境で実行している場合、複数のトレースリスナーに問題があります。MSTestは、最初のテストの後に破棄されるストリームを使用しているSystem.Diagnostics.TextWriterTraceListenerを追加しています。回避策は、デフォルト以外のすべてのTraceリスナーを削除するだけで、mstestが追加されたリスナーを効果的に削除します。この問題は、mstestによって作成されたトレースストリームの不適切な処理に関連しているようです。以前、mstestがテストごとにAppDomainを作成したと述べました。本当じゃない。

ここでMicrosoftにバグレポートを提出したようですが、有用なフィードバックはありませんでした。うまくいけば、このクイックフィックスが私と同じようにあなたのために働くでしょう。

于 2009-09-01T22:03:36.203 に答える