none
C#でスレッドエラー RRS feed

  • 質問

  • Visual Studio2005でC#のプロジェクトを作成しています。
    ところが、デバッグモードで、FileDialogを表示する際にエラーが起きるようになってしまいました。以下にエラー文を引用します。

    > System.Threading.ThreadStateException はハンドルされませんでした。
    > Message="OLE が呼び出される前に、現在のスレッドが Single Thread Apartment (STA) モードに設定されていなければなりません。Main 関数に STAThreadAttribute
    > が設定されていることを確認してください。 この例外はデバッガがプロセスにアタッチされている場合にのみ発生します。"

    Main関数にSTAThreadAttributeは設定してあります。そもそも、今までは、何もエラーが起きていなかったのに、後述する操作をした後に、デバッグの時にのみこのエラーが発生するようになってしまいました。
    その操作とは、別のプロジェクトでMicrosoft office 12.0 object libraryの参照を追加し、Excel2007に出力するプログラムをデバッグモードで実行した操作です。

    対処法を教えて頂けないでしょうか。
    2008年3月24日 6:27

回答

  • スタックトレースとはメソッドの呼び出し履歴です。予想外なところから要求されている可能性がありますから。

    イミディエイトウィンドウで System.Threading.Thread.CurrentThread とかやれば表示されませんか?

    2008年3月27日 13:18
  •  らぴた さんからの引用

    Program.Mainにブレークを貼って、確認してみましたが、通っていました。
    その際に、スレッドの状態も確認してみましたが、MTAになっていました。

    なるほど。こうなると、原因が分かりませんね。

     

    米国のフォーラムでは「Thread作ったら?」みたいな解決策が提示されていますが、本質的な解決にはなりませんね。

     

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=742724&SiteID=1&pageid=0

    2008年4月2日 15:52
    モデレータ

すべての返信

  •  らぴた さんからの引用

    ところが、デバッグモードで、FileDialogを表示する際にエラーが起きるようになってしまいました。以下にエラー文を引用します。

    このFileDialogを出しているのはメインのスレッドですか?

    それとも、BackgroundWorkerコンポーネントやThreadクラスで作ったスレッドですか?

     らぴた さんからの引用

    Main関数にSTAThreadAttributeは設定してあります。そもそも、今までは、何もエラーが起きていなかったのに、後述する操作をした後に、デバッグの時にのみこのエラーが発生するようになってしまいました。
    その操作とは、別のプロジェクトでMicrosoft office 12.0 object libraryの参照を追加し、Excel2007に出力するプログラムをデバッグモードで実行した操作です。

    OfficeのライブラリはSTAが必要なのに、現状はMTAで実行されているからでしょう。

     

    現時点で考えられるパターン

    ・BackgroundWorkerのスレッドでFileDialogを表示している(BackgroundWorkerのスレッドはMTA)

    ・ThreadクラスでSTAに設定せずにスレッドを動かし、そのスレッドでFileDialogを表示している(Threadクラスで作成したスレッドのデフォルトはMTAになる)

    2008年3月24日 13:46
    モデレータ
  • 回答ありがとうございます。回答があるのに気づくのが遅れてしまい、返信が遅くなってしまい申し訳ありません。

     Azulean さんからの引用

    このFileDialogを出しているのはメインのスレッドですか?

    それとも、BackgroundWorkerコンポーネントやThreadクラスで作ったスレッドですか?


    FileDialogは、メインのスレッドで出しています。
    Threadクラス、BackgroundWorkerコンポーネントのいずれも使っていません。

     Azulean さんからの引用

    OfficeのライブラリはSTAが必要なのに、現状はMTAで実行されているからでしょう。


    現時点で考えられるパターン

    ・BackgroundWorkerのスレッドでFileDialogを表示している(BackgroundWorkerのスレッドはMTA)

    ・ThreadクラスでSTAに設定せずにスレッドを動かし、そのスレッドでFileDialogを表示している(Threadクラスで作成したスレッドのデフォルトはMTAになる)

    つまり、何かの原因で、現在MTAで実行されているのが問題ということですね。


    以下の操作を試してみました。

    1.一度、プロジェクトのコピーを作った後に、開始クラス以外のすべてクラスを削除して、自分で加えた参照もすべて削除して、FileDialogを呼び出すだけの機能しかないプログラムに修正して、実行してみました。

    それなのに、また同じエラーが起きてしまいました。

    2.もう一度、まったく同じ名前でプロジェクトを作成して、全コードをコピーして、実行してみました。

    この場合、エラーが起きず、正常に動作しました。


    全然根拠はないのですが、Officeのライブラリを使った時に、Visual Studioの環境設定の何かが変わってしまったのではないかと思っているのですが、関係はないでしょうか?


    一応、上述した2.の方法で、修正できることが分かりましたが、少なくとも後2つのプロジェクトが影響を受けていることが分かっていて、すべてのファイルをコピー&ペーストしていくことは、可能ではありますが手間ですし、気持ちも悪いです。何より、次回、またOfficeライブラリを使った時に同じことが起きるかと思うと、このままではOfficeライブラリが恐くて使えません。引き続き、解決策を知りたいです。

    何かアドバイスをよろしくお願いします。

    2008年3月27日 4:12
  • 取り敢えず、FileDialog 表示箇所にブレークポイント張ってスタックトレース見るとかイミディエイトウィンドウで現在のスレッドの状態を確認するとかしたらどうでしょうか。

    2008年3月27日 4:57
  • アドバイスありがとうございます。
     Hongliang さんからの引用

    取り敢えず、FileDialog 表示箇所にブレークポイント張ってスタックトレース見るとかイミディエイトウィンドウで現在のスレッドの状態を確認するとかしたらどうでしょうか。


    FileDialog表示部分にブレークポイントを張ってみました。出力の後半部分のみを以下に引用します。

    ・・・(省略)・・・・\System.Configuration.dll' が読み込まれ、シンボルの読み込みがスキップされました。モジュールが最適化されていて、デバッグ オプションの [マイ コードのみ] 設定が有効にされています。
    FogeProgram.vshost.exe' (マネージ型): 'C:\WINDOWS\assembly\GAC_MSIL\System.Windows.Forms.resources\2.0.0.0_ja_b77a5c561934e089\System.Windows.Forms.resources.dll' が読み込まれました。シンボルは読み込まれませんでした。
    'System.Threading.ThreadStateException' の初回例外が System.Windows.Forms.dll で発生しました。

    スレッドの状態をイミディエイトウィンドウで確認した方が良いとのことでしたが、新しくスレッドを作っていないのに確認できるものなのでしょうか?どのようにして状態を確認すればよいのか、まったく検討もつきません。
    申し訳ありませんが、スレッドの状態の確認の仕方について教えてもらえないでしょうか?

    2008年3月27日 11:19
  • スタックトレースとはメソッドの呼び出し履歴です。予想外なところから要求されている可能性がありますから。

    イミディエイトウィンドウで System.Threading.Thread.CurrentThread とかやれば表示されませんか?

    2008年3月27日 13:18
  • やり方を教えていただきありがとうございます。

    プログラムの開始時点から既に、MTAになっていたようです。
    スレッドの状態を以下に引用します。
    System.Threading.Thread.CurrentThread
    {System.Threading.Thread}
        base {System.Runtime.ConstrainedExecution.CriticalFinalizerObject}: {System.Threading.Thread}
        ApartmentState: MTA
        CurrentCulture: {ja-JP}
        CurrentUICulture: {ja-JP}
        ExecutionContext: {System.Threading.ExecutionContext}
        IsAlive: true
        IsBackground: false
        IsThreadPoolThread: false
        ManagedThreadId: 10
        Name: null
        Priority: Normal
        ThreadState: Running

    呼び出し履歴についても、特に変なところから要求されていたりしていないので、問題ないようです。
    2008年3月28日 3:41
  •  らぴた さんからの引用

    呼び出し履歴についても、特に変なところから要求されていたりしていないので、問題ないようです。

    問題なかったということは、呼び出し履歴を辿ると「Program.Main」が出てきたと言うことですか?

    そのProgram.Mainには「[STAThread]」がついているということですか?

    2008年3月30日 22:07
    モデレータ
  •  Azulean さんからの引用

    問題なかったということは、呼び出し履歴を辿ると「Program.Main」が出てきたと言うことですか?

    そのProgram.Mainには「[STAThread]」がついているということですか?



    呼び出し履歴の最初に「Program.Main」が出て来て、その次の呼び出し履歴のところでエラーになります。エラーになる部分の呼び出し履歴の表示は以下のようになっていました。
    fogefoge.exe!fogefoge.Form1.btRef_Click(object sender = {Text = "参照"}, System.EventArgs e = {X = 45 Y = 14 Button = Left}) 行 44    C#

    「Program.Main」は、何も編集していないのですが、以下のようになっています。
    Code Snippet

    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;

    namespace fogefoge {
        static class Program {
            /// <summary>
            /// アプリケーションのメイン エントリ ポイントです。
            /// </summary>
            [STAThread]
            static void Main() {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }
        }
    }

    もしかして、[STAThread]を記載する場所が違うのでしょうか?
    2008年3月31日 3:07
  •  らぴた さんからの引用

    「Program.Main」は、何も編集していないのですが、以下のようになっています。

    考えにくいのですが、そのProgram.Mainは通っていますか?ブレーク貼って頂けると確認できます。

     らぴた さんからの引用
    もしかして、[STAThread]を記載する場所が違うのでしょうか?
    合っているはずです。
    手元で新規プロジェクトを作成し、STAThreadとなっている部分をあえてMTAThreadにすると同じ例外が発生しますが、STAThreadに戻すと例外は発生しません。
     
     
    どんな可能性があるだろうかなぁ…。
    プロジェクトの設定が何か悪くなっているとかは考えられなくもないですが、現状は何とも言えないです。
    2008年3月31日 14:13
    モデレータ
  • 回答ありがとうございます。
     Azulean さんからの引用

    考えにくいのですが、そのProgram.Mainは通っていますか?ブレーク貼って頂けると確認できます。


    Program.Mainにブレークを貼って、確認してみましたが、通っていました。
    その際に、スレッドの状態も確認してみましたが、MTAになっていました。

    2008年4月2日 12:51
  •  らぴた さんからの引用

    Program.Mainにブレークを貼って、確認してみましたが、通っていました。
    その際に、スレッドの状態も確認してみましたが、MTAになっていました。

    なるほど。こうなると、原因が分かりませんね。

     

    米国のフォーラムでは「Thread作ったら?」みたいな解決策が提示されていますが、本質的な解決にはなりませんね。

     

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=742724&SiteID=1&pageid=0

    2008年4月2日 15:52
    モデレータ
  •  Azulean さんからの引用

    米国のフォーラムでは「Thread作ったら?」みたいな解決策が提示されていますが、本質的な解決にはなりませんね。

     

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=742724&SiteID=1&pageid=0



    教えていただいた先の方法で、エラーになってしまっていた他のプロジェクトも正常に動作するようになりました。
    すべてコピー&ペーストしてやり直さなければいけないかと思っていただけに、最小限の変更で済んだので助かりました。

    依然として原因が分からなくて気持ち悪いのですが、また、同じトラブルがあったときに、とりあえずエラーを回避する手法が得られたので安心できました。
    ありがとうございました。



    2008年4月3日 3:00
  •  らぴた さんからの引用

    > System.Threading.ThreadStateException はハンドルされませんでした。
    > Message="OLE が呼び出される前に、現在のスレッドが Single Thread Apartment (STA) モードに設定されていなければなりません。Main 関数に STAThreadAttribute 
    > が設定されていることを確認してください。 この例外はデバッガがプロセスにアタッチされている場合にのみ発生します。"

    私も同様のエラーが発生し、原因不明ですが、
    プロジェクトの/bin/Debug,/bin/Release以下のファイルおよび
    /objをすべて削除し、プロジェクトのクリーン&リビルドをして直りました。
    どこかのファイルがおかしくなったのだと思います。
    2008年12月10日 7:38