none
マルチスレッドからPictureboxの値を変更する RRS feed

  • 質問

  • こんにちは、プログラム中でわからないことがあったので質問させていただきます。

        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                AppliCation application = new AppliCation();

                Thread application_thread = new Thread(application.run);
                application_thread.Start(this);
            }

            public void pb1_gazou_hyouzi(FileStream fs)
            {
                this.Invoke(new MethodInvoker(delegate()
     {
         pictureBox1.Image = System.Drawing.Image.FromStream(fs);
     }));
               
            }
        }

        public class AppliCation
        {
            public void run(object form)
            {
                Form1 form1 = (Form1)form;
             
                    byte[] bb = new byte[1024];
                    int readsize = 0;
                    FileStream fs = new FileStream("C:\\tmp.jpg", FileMode.Create, FileAccess.Write);

                    try
                    {
                        form1.pb1_gazou_hyouzi(fs);
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(e.ToString());
                    }

                    fs.Close();
                }
            }

    このようなプログラムをはしらして、フォーム上に張り付けているPictureboxのImageを変更したいのですが、これを実行すると
    メッセージボックスに「指定されたパラメータは有効ではありません」と表示されてしまいます。
    Process.Start("C:\\tmp.jpg"); この用に書いたプログラムは正常に動くのでファイルが存在しないということはないと思うのですが何が原因でエラーが表示されてしまうのかわかりません。
    よろしければ御回答ください。

    あと、自分はまだ学生ですので少し初心者向けの回答にしていただけると助かります。

    2009年2月26日 9:19

回答

  • 記載されてるコードがどうやって生まれてきたのかがわかりませんが、アプローチは少なくとも変えたほうがいいです。
    例えば、記載されているコードから抽出したイメージの読み込み部分のコアとなる以下のコードでも同じエラーがでますよね?

    private void Form1_Load(object sender, EventArgs e)  
    {  
        FileStream fs = new FileStream("C:\\tmp.jpg", FileMode.Create, FileAccess.Write);  
        pictureBox1.Image = System.Drawing.Image.FromStream(fs);  
    }  
     

    つまり、ファイルを読み込んできて、それをPictureBoxに表示させるということが実現できていないので、まずはこれを実現させてからマルチスレッドなどを考えたほうがいいです。
    じゃないと、それがマルチスレッド特有の問題なのかそうでないのかが断定できないからです。

    適当ですが、こんなのどうでしょう?

    public partial class Form1 : Form  
    {  
        public Form1()  
        {  
            InitializeComponent();  
        }  
     
        private void Form1_Load(object sender, EventArgs e)  
        {  
            ParameterizedThreadStart paramThreadDelegate = new ParameterizedThreadStart(this.LoadImage);  
     
            Thread th = new Thread(paramThreadDelegate);  
            th.Start(@"C:\tmp.jpg");  
        }  
     
        public void LoadImage(object imagePath)  
        {  
            this.pictureBox1.Image = Image.FromFile(imagePath.ToString());  
        }  
    }  
     
    • 回答としてマーク SE_lain 2009年3月4日 0:09
    2009年2月26日 16:16

すべての返信

  • FileStreamをFileAccsess.Write(書き出し専用、つまり読み込み禁止)でopenしています。PictureBoxに読み込むことは無理でしょう。

    ちなみに、呼び出しがクラス間を行ったり来たりするのはかなり悪い設計です。
    どこで何が必要になり、そのためにどこに何を渡せばいいのか、そういったことを整理した方がいいですよ。
    2009年2月26日 10:30
  • 記載されてるコードがどうやって生まれてきたのかがわかりませんが、アプローチは少なくとも変えたほうがいいです。
    例えば、記載されているコードから抽出したイメージの読み込み部分のコアとなる以下のコードでも同じエラーがでますよね?

    private void Form1_Load(object sender, EventArgs e)  
    {  
        FileStream fs = new FileStream("C:\\tmp.jpg", FileMode.Create, FileAccess.Write);  
        pictureBox1.Image = System.Drawing.Image.FromStream(fs);  
    }  
     

    つまり、ファイルを読み込んできて、それをPictureBoxに表示させるということが実現できていないので、まずはこれを実現させてからマルチスレッドなどを考えたほうがいいです。
    じゃないと、それがマルチスレッド特有の問題なのかそうでないのかが断定できないからです。

    適当ですが、こんなのどうでしょう?

    public partial class Form1 : Form  
    {  
        public Form1()  
        {  
            InitializeComponent();  
        }  
     
        private void Form1_Load(object sender, EventArgs e)  
        {  
            ParameterizedThreadStart paramThreadDelegate = new ParameterizedThreadStart(this.LoadImage);  
     
            Thread th = new Thread(paramThreadDelegate);  
            th.Start(@"C:\tmp.jpg");  
        }  
     
        public void LoadImage(object imagePath)  
        {  
            this.pictureBox1.Image = Image.FromFile(imagePath.ToString());  
        }  
    }  
     
    • 回答としてマーク SE_lain 2009年3月4日 0:09
    2009年2月26日 16:16
  •  <<佐祐理さん
    返事遅くなってすいません、お返事ありがとうございます。

    <<FileStreamをFileAccsess・・・
    これは恥ずかしながら後で気づいて読み込み可能にしたのですが、同じエラーになりました。どこかほかの所にも原因があるようです。

    <<ちなみに、呼び出しがクラス・・・
    呼び出しというのは引数のことですか?クラスの設計に関しては勉強したいので、本題からはそれますが詳しく教えていただけるとありがたいです。
    2009年3月2日 7:29
  • <<CrimsonPorkさん
    返事遅くなってしまってすいません。お返事ありがとうございます。

    <<例えば、記載されている・・・
    なるほどマルチスレッドの問題ではなかったのですね・・・今後はもっとしぼってから質問させていただきたいと思います。


    <<適当ですが、こんなのどうでしょう・・・
    このソースコードを実装するとちゃんと動きました。ありがとうございます。
    2009年3月2日 7:36
  • SE_lain の発言:

    呼び出しというのは引数のことですか?クラスの設計に関しては勉強したいので、本題からはそれますが詳しく教えていただけるとありがたいです。

    本題の方は解決したのでしょうか?

    Form1.Form1_Load()
    →AppliCation.run()
    →Form1.pb1_gazou_hyouzi()
    とお互いが相手のクラスメンバを呼び出し合っている構造のことです。
    基本的にはどちらかのクラスが相手のクラスを呼び出すだけの一方通行の依存関係であるべきです。
    2009年3月2日 12:12
  • SE_lainさん の発言:

    <<適当ですが、こんなのどうでしょう・・・
    このソースコードを実装するとちゃんと動きました。ありがとうございます。

    コントロールは、コントロールが所属しているスレッドで操作する必要があります。LoadImageメソッドは別のスレッドですから、最初に書かれていたようにInvokeを使わなければならないと思います。たまたま動いているという状況なんじゃないかと思います。

    #.NET 1.1の時はたまたま動くことが多かったのですが、.NET 2.0からは厳しくなったような気がしていたけどなぁ。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年3月3日 7:49
    モデレータ
  • trapemiya の発言:

    コントロールは、コントロールが所属しているスレッドで操作する必要があります。LoadImageメソッドは別のスレッドですから、最初に書かれていたようにInvokeを使わなければならないと思います。たまたま動いているという状況なんじゃないかと思います。

    その点についてですが、pb1_gazou_hyouzi()はthis.Invoke()を使ってますよ?
    2009年3月3日 9:14
  • 佐祐理さん の発言:

    その点についてですが、pb1_gazou_hyouzi()はthis.Invoke()を使ってますよ?

    えっと、以下の「最初に書かれていたように」っていうのがpb1_gazou_hyouzi()を指したつもりだったのですが、わかりにくかったかもしれません。LoadImageでもInvoke()を使いましょうということです。

    trapemiya の発言:

    最初に書かれていたようにInvokeを使わなければならないと思います


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年3月3日 11:08
    モデレータ
  •  <<佐祐理さん

    お返事ありがとうございます。本題のほうはおかげさまで解決できました。

    なるほど・・・互いのメンバを呼び出しあうというのはよくない設計なのですね。ありがとうございます。勉強になりました。
    2009年3月3日 23:28
  • <<trapemiyaさん

    お返事ありがとうございます。確かにスレッドが違うのに、操作できるのはおかしいですね。Invokeメソッドを使って実装してみても動かすことができました。ありがとうございます。
    2009年3月4日 0:07
  •  おはようございます!(^^)!ふ~です。

     Invoke()、とうとう、DotNetの基本的な技術の一つに当たったようです。SE_lainさんは学生さんですので、これは何の為に必要で何をしているのか興味があるのではと思います。しかし、今まで、我々、日本のエンジニアの声は小さかった。あるパターンをコピー&ペーストするだけで、納期に追われています。

    //Windowsフォームで別スレッドからコントロールを操作するには?
    http://www.atmarkit.co.jp/fdotnet/dotnettips/312ctrlinvoke/ctrlinvoke.html

    抜粋『Invokeメソッドが必要かどうかを示すInvokeRequiredプロパティ』

    private void button1_Click(object sender, System.EventArgs e)  
    {  
      Thread t = new Thread(new ThreadStart(worker));  
      t.Start();  
    }  
     
    delegate void SetFocusDelegate();  
     
    void SetFocus()  
    {  
      if (InvokeRequired)  
      {  
        // 別スレッドから呼び出された場合  
        Invoke(new SetFocusDelegate(SetFocus));  
        return;  
      }  
      textBox2.Focus();  
    }  
     
    void worker()  
    {  
      SetFocus();  
    }  

    取り合えず、考えている暇があれば、早く仕上げて納品せよと言うわけです。

    皆、納得などしてはおりません。我々は、マネージコードだけで、可読性が良く、汎用的なプログラムを作成している筈であったが、Invoke()を使うのは意外だ。 Invoke()はオモタイ処理だ。なぜ必要なのだ。との声があると思います。

    //フリー百科事典『ウィキペディア(Wikipedia)』
    http://ja.wikipedia.org/wiki/P/Invoke

    //Control.Invoke メソッド (Delegate)
    http://msdn.microsoft.com/ja-jp/library/zyzhdc6b.aspx

    MSDNライブラリに情報は少なかった。しかし、中国のエンジニアの方は詳しかった!?

    //マネージ コードとアンマネージ コード間でマーシャリングする
    http://msdn.microsoft.com/ja-jp/magazine/cc164193.aspx

    最も、Invoke()の解析をしたいと思えばソースコードも入手可能です。

    // .NETのソースコード
    http://referencesource.microsoft.com/netframework.aspx

    //スレッド: [csharpll:0226] <救>EventHandlerでControl.Invoke
    http://ml.tietew.jp/cppll/csharpll/thread_articles/226

    『Windowsフォームで別スレッドからコントロールを操作するにはInvke()が必要です。』を簡単に説明できる良い例があると良いのですが?
    2009年3月4日 1:02
  • Control.Invoke()とP/Invokeは別モノですよ。
    Invoke()の必要性については、SendMessage()でワーカースレッドをブロックしてしまうわけにもいかないので、UIスレッドで呼び出すこと、と理解していました。

    trapemiyaさん、コメントを読み違えていました、スミマセン。
    2009年3月4日 10:18
  •  こんばんは!(^^)!ふ~です。

    >Control.Invoke()とP/Invokeは別モノですよ。

    これは実に良いご意見と思います。Control.Invoke()は、「別スレッドからフォーム、コントロールを扱う」で、P/Invoke()は「Platform Invoke、プラットフォーム呼び出し」です。全く異なるではないか?とおっしゃるのはごもっともです。

    しかし、理解し易い良い資料を探す事に重点を置きますと、どちらも「マーシャリング」を理解する必要がございます。ここが共通点と思います。

    P/Invoke()は、アンマネージとマネージでマーシャリングを行わないと行けないのは日常的な作業ですが、Control.Invoke()では関係ないでしょう?と言うことと思います。。。ところが

    // NETマルチスレッドプログラミング 2:非同期デリゲートとスレッドプール
    http://codezine.jp/article/detail/139?p=1

    ここの説明が一番良かったので抜粋します。
    『Consoleクラスはスレッドセーフであり、マルチスレッド操作に対して安全が保障されています。ところが、Windowsアプリケーションのコントロール(フォームを含む)は違います。Controlクラスでスレッドセーフが保障されているのは、Invoke、BeginInvoke、EndInvoke、CreateGraphicsメソッドおよびInvokeRequiredプロパティのみです。さらにWindowsフォームはシングルスレッドアパートメント(STA)モデルを使用しており、コントロールのメソッド(あるいはプロパティ)はそのコントロールを作成したスレッド(UIスレッド)からしか呼び出すことができません。つまり、スレッドセーフが保障されているメソッドを除き、コントロールのメソッドを別スレッドから直接呼び出してはいけません。
    これを解決するには、スレッドの境界を越えて実行を行う、マーシャリングが必要になります。.NET FrameworkのControlクラスでは、マーシャリングを確実かつ効率よく行う方法として、Invoke、BeginInvoke、およびEndInvokeメソッドが用意されています。』

    と言うことで、私は「マーシャリング」の説明資料を上げました。(メモリ管理、サンクやデリゲートなどの考え方は使える)

    更に、追加資料です。

    //方法 : バックグラウンド スレッドを使用してファイルを検索する
    http://msdn.microsoft.com/ja-jp/library/3s8xdz5c.aspx

    //方法 : Windows フォーム コントロールのスレッド セーフな呼び出しを行う
    http://msdn.microsoft.com/ja-jp/library/ms171728(VS.80).aspx

    以上

    2009年3月4日 12:02
  • !(^^)!ふ~ の発言:

    >Control.Invoke()とP/Invokeは別モノですよ。

    しかし、理解し易い良い資料を探す事に重点を置きますと、どちらも「マーシャリング」を理解する必要がございます。ここが共通点と思います。

    説明なくその2つを並べると理解していないだけに見えますし、先のコメントだけを読んだ人には誤解を与えますよ。
    その上で…

    Control.Invoke()は、参考にあげている「方法 : バックグラウンド スレッドを使用してファイルを検索する」にも書かれていますが
    STA モデルでは、コントロールを作成したスレッドの外部から呼び出される必要があるすべてのメソッドを、そのコントロールの作成スレッドにマーシャリングする (そのコントロールの作成スレッドで実行する) 必要があります。
    言い換えると、メッセージループを待ち、実行可能になった時点でdelegateを実行する。スレッドをまたぐだけの行為です。

    もう一方のP/Invokeは、相互運用マーシャリングで説明されていますが、アンマネージメモリ上でのデータレイアウトの話で、スレッドは絡みません。

    という違いがあり、同じマーシャリングという言葉を使用していますが、別々の概念です。
    2009年3月5日 1:40
  • おはようございます!(^^)!ふ~です。

    >Invoke()の必要性については、SendMessage()でワーカースレッドをブロックしてしまうわけにもいかないので、UIスレッドで呼び出すこと、と理解していました。

    私も、実際にはそのような流れになると思います。
    ここで少々、長くなりましたので、要点のまとめです。

    ■なぜ、別スレッドからWindowsフォームのコントロールは制御できないのか!?

    1.Windowsフォームはシングルスレッドアパートメント(STA)モデルを使用しており、
    コントロールのメソッド(あるいはプロパティ)はそのコントロールを作成したスレッド(UIスレッド)
    からしか呼び出すことができません。(キーワードは COM )

    2.これを解決するには、スレッドの境界を越えて実行を行う、マーシャリングが必要になる。

    (説明)
    先のソースサンプルのText.SetFocus()で考えて見ますと、マネージ側の我々のプログラムにある
    SetFocus()と言うテキストコントロールを制御するメソッドは、WindowsフォームのUIスレッド側
    から呼び出し、実行すれば良いことになります。

    ■次に、どのようにして、WindowsフォームのUIスレッド側からSetFocus()を実行するのか!?
    (手順)
    1.Windowsフォームのウィンドウ・ハンドルを取得する。
    2.UIスレッド側から呼出せるエントリースレッドを作る。(SetFocus()デリゲート情報も含める)
    3.threadCallbackMessageメッセージを作成する。
    4.エントリースレッドをthreadCallbackList.Enqueue()のキューへ登録する。
    5.UnsafeNativeMethods.PostMessage(new HandleRef(this, Handle), threadCallbackMessage, IntPtr.Zero, IntPtr.Zero);
    6.WaitForWaitHandle(tme.AsyncWaitHandle)で、WindowsフォームのUIスレッドがSetFocus()メソッドを実行するまで待つ

    (説明)
    このメッセージを、我々のマネージ側からWindowsフォームのUIスレッド側へ送る事ができる。
    このメッセージをWindowsフォームのUIスレッド側は、受信すると、threadCallbackList.Enqueue()キューの中にある
    エントリースレッドを見つけ、SetFocus()のデリゲート情報を使い、SetFocus()メソッドを実行する。これを簡単にInvoke(new SetFocusDelegate(SetFocus));と一行で行っています。

    2009年3月5日 2:30
  •  こんばんは!(^^)!ふ~です。

    マーシャリングと言っていれば何となく説明したような気分になる魔法の言葉とも思えます。
    でも、機能を実装すると、全く別物になる場合が有りますね。確かに。

    中国の方のご説明は、上手いと思います。アンマネージ環境、マネージ環境、GC、アンマネージコード、CLR、サンク、デリゲート、ユーザーコードを定義して、変数を説明しておりましたが、メソッドでも上手く説明できると思います。

    更に、アンマネージ環境とマネージ環境のメッセージ処理や、スレッドコールバックリストキュー処理の概念の説明が上手く説明できればなんとなく見えて来るのではと思っております。つまり、アンマネージ環境とマネージ環境の作法をマーシャリングと捉えております。

    以上 よろしくお願い致します。
    2009年3月5日 3:19
  •  http://www.excite.co.jp/dictionary/english_japanese/?search=marshal&match=beginswith&dictionary=NEW_EJJE&block=39955&offset=28&title=marshal

    そんな難しく考えなくても、「整理する」「整頓させる」なのだから、「スレッドの境界を越えたデータの取り扱いを整理する」でいいやん。マネージ、アンマネージの間でも、「誰が管理するの?」ってところを「整理する」必要があるやん。
    Jitta@わんくま同盟
    2009年3月5日 3:32
  • こんにちは!(^^)!ふ~です。

    >そうですね。『marshal』は、「整理する」「整頓させる」でした。
    私は、リトルチャロの英会話少し聞いてますが直ぐに忘れて身に付きません。これからの学生さんは、英会話で苦労しても、徳を得る方が遥かに大きい時代ですね。(生まれて直ぐに英会話頭脳に設定する方が良いのですが、一寸、日本では無理ですね)
    本題ですが、学生さんに、Invoke()の仕組みなど、教えている学校があるんでしょうか?そもそも教科書が無いのではと思います。海外では、学生時代にLinuxの原型を作ったとも聞きますから、プログラマー人生で重要な時期です。
    私は、個人、出版社、クラブ、大学、研究機関などで .NETのソースコードを解析して、学生さんが本格的プログラムを学べるよう教科書を作成する事ができれば、喜ばしいと思いますが、皆さまはどうでしょうか?
    • 編集済み !(^^)!ふ~ 2009年3月13日 13:54 trapemiyaさんご指摘で Invoke -> marshalに訂正する
    2009年3月5日 4:30
  • !(^^)!ふ~ の発言:

    (生まれて直ぐに英会話頭脳に設定する方が良いのですが、一寸、日本では無理ですね)

    日本語さえ、操るのに苦労しているのに!?

    ま、それはいいや。


    本題ですが、学生さんに、Invoke()の仕組みなど、教えている学校があるんでしょうか?そもそも教科書が無いのではと思います。海外では、学生時代にLinuxの原型を作ったとも聞きますから、プログラマー人生で重要な時期です。

    それを知る必要があるのでしょうか?あ、いや、必要はあるんだけど。

    ん~。。。物事には、順番があると思います。Invoke の仕組みというか、なぜ Invoke することが必要なのかを知ることより先に、知っておかなければならないことがあるのではないでしょうか。


    私は、仕組みさえ知っていれば、後は応用であると思います。しかし、仕組みさえ知らずに、ナントカしようとしているのが現状であると認識しています。

    ここで「仕組み」とは、言語仕様ではありません。プログラムがなぜ動くのかでもありません。コンピュータに対して命令を与える方法、コンピュータが理解できる命令を組み立てる方法です。


    今回の質問を見てみますと、Invoke の使いどころが間違っていると言えます。コードを見てみます。

    Form1_Load メソッドでスレッドを作成し、AppliCation クラスの run メソッドをコールします。run メソッドの引数に、form のインスタンスを渡します。run メソッドで、form インスタンスの pb1_gazou_hyouzi メソッドを呼び出し、その中で this.Invoke としています。

    Form.Invoke を見ると、コントロールの基になるウィンドウ ハンドルを所有するスレッド上で、指定したデリゲートを実行します。と書かれています。では、ここで「コントロール」とはなんでしょう?呼び出しているメソッドが存在しているコントロールなのか、Form なのか、どちらかだと思われます。もし、呼び出しメソッドだとすると、今回のように Control から派生していないクラスに存在するメソッドから呼び出された場合、コントロールは存在しないことになります。これはおかしいでしょう。ですから、コントロールは、Form そのものだと理解できるのではないでしょうか。

    おそらく、Invoke しなければならないというところまではたどり着いたのだと思います。なので、Form1 のメソッドの中で、this.Invoke としているのだと思います。ただ、他の方からご指摘があるように、その他のコードにミスがあります。何らかのエラーが出たために試行錯誤を繰り返している最中のコードだと思うのですが、試行錯誤の方法が間違っているために理解から遠ざかってしまったように思えます。
    ところで、MSDN にサンプル コードも掲載してあります。このサンプルコードを見てみましょう。そうすると run メソッドの中から form.invoke(form.pb1_gazou_hyouzi) とすればよかったことがわかるのではないでしょうか。

    1 public partial class Form1 : Form  
    2 {  
    3     public Form1()  
    4     {  
    5         InitializeComponent();  
    6     }  
    7  
    8     private void Form1_Load(object sender, EventArgs e)  
    9     {  
    10         AppliCation application = new AppliCation();  
    11  
    12         Thread application_thread = new Thread(application.run);  
    13         application_thread.Start(this);  
    14         // この後、スレッドを Join しなきゃいけないと思うけど?  
    15     }  
    16  
    17     public void pb1_gazou_hyouzi(FileStream fs)  
    18     {  
    19         pictureBox1.Image = System.Drawing.Image.FromStream(fs);  
    20     }  
    21 }  
    22  
    23 public class AppliCation  
    24 {  
    25     public void run(object form)  
    26     {  
    27         Form1 form1 = form as Form1;  
    28         if (form1 == null) { return; }  
    29         using (FileStream fs = new FileStream(@"C:\tmp.jpg", FileMode.Open, FileAccess.Read))  
    30         {  
    31  
    32             try 
    33             {  
    34                 form1.Invoke(pb1_gazou_hyouzi, new object[] {fs});  
    35             }  
    36             catch (Exception e)  
    37             {  
    38                 // これも、実行できる保証はなかったんじゃないかな?  
    39                 MessageBox.Show(e.ToString());  
    40             }  
    41  
    42             fs.Close();  
    43         }  
    44     }  
    45 }  
    46  

    つまり、Invoke とか Mashal とかの仕組みを知るよりも先に、「自分がしたい事を実行する手順を考え、その手順を用意されている言語の最小実行単位にまで落とし込む」、「リファレンスを読む(リファレンスにあるサンプル コードの意味を読む)」といったことの方が重要かと思います。

    もちろん、発展として、「なぜ動くのか」という仕組みを知っていることは重要です。


    Jitta@わんくま同盟
    2009年3月13日 12:39
  •  
    !(^^)!ふ~さん の発言:

    >そうですね。Invokeは、「整理する」「整頓させる」でした。

    いえ、「整理する」「整頓させる」はマーシャリングです。飛行機が駐機する時に飛行機を整列させている人がいますが、マーシャラーっていいます。(余談です)
    プログラムの世界でマーシャリングと言えば、データを整理して(まとめて)、受け渡しているわけです。つまり、異なる者同士でデータが受け渡せるようにデータの整合性を取っているんですね。

    Invokeは呼び出すというような意味です。つまり、自分のスレッドからUIスレッドに、「あなたのスレッドであなたが良いタイミングでこのメソッドを呼び出してね。」ってお願いしているわけです。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年3月13日 13:30
    モデレータ
  • こんばんは!(^^)!ふ~です。

    Jittaさん、学生さん思いで、とても良いこといいますね。私には厳しいですが。。。
    >つまり、Invoke とか Mashal とかの仕組みを知るよりも先に、「自分がしたい事を実行する手順を考え、その手順を用意されてい>る言語の最小実行単位にまで落とし込む」、「リファレンスを読む(リファレンスにあるサンプル コードの意味を読む)」といったことの>方が重要かと思います。もちろん、発展として、「なぜ動くのか」という仕組みを知っていることは重要です。

    私も、そう思います。最初から、難しいことを考えると、ストレスも上がり、上手いアプローチとは思えません。自分に易しい、簡単と思う所からリラックスしながらStep by Stepと、深めるのがプログラミングの上達にも良いようです。

    trapemiyaさん、こんばんは、有難うございます。
    >そうですね。Invokeは、「整理する」「整頓させる」でした。

    これを書いたのは私ですが、今までマーシャル(marshal)のつもりでおりましたが、しかし、今日は、どう見ましても
    インボーク(Invoke)と書いて有ります。
    私もそろそろオーバーホールしないと駄目なようです。有難く訂正させていただきました。有難うございます。
    2009年3月13日 14:43