2016-09-20 10 views
0

にスレッドセーフなアクセスのためのベストプラクティスは何であるコードに時間がかかり、必要なようだより私はすべてのコントロールのすべてのメソッドとプロパティのために1つを書くことになるかもしれません。がスレッドセーフな方法でコントロールへのアクセスを制御し

これをコードするより効率的な方法はありますか?理想的には、アプリケーション全体の1つのサブアイテムです。アクセスするコントロールのプロパティとメソッドに関係なく使用できます。

+1

あなたのボーナスポイント***特定のプログラミング上の問題は***ありますか?私が見ているのは、広範囲になる可能性があるので、話題にならない意見が欲しいということです...また、例外を投げる理由は、コントロールへのアクセスが本質的にスレッドセーフではないからです。たとえば、2つ以上のスレッドがコントロールの状態を操作している場合、競合状態やデッドロックなどの不整合な状態に制御を強制することができます。 ********************************************************************************************************************************************************************** – Codexer

+0

あなたの質問に答える最後のもう1つのメモ 'これをコード化するより効率的な方法はありますか? '、***デリゲートを使ってUIを非同期的に呼び出すと、スレッドセーフなメソッドを呼び出すことができますスレッド)を使用して、UIで必要なものを更新します。 – Codexer

+0

'ボーナスポイントの場合は...ボーナスポイントは何と言っていますか? 1つの投稿で2つの質問をするだけの透明な方法です。 – Plutonix

答えて

3

私の意見では(あなたのように)実行することがベストプラクティスです。一般的なベストプラクティスはないと思うが、多くの人がControl.Invoke()Control.BeginInvoke()メソッドを使用している。スレッドセーフな方法でコントロールへのアクセス

私は、次のオーバーと私はすべてのすべてのメソッドとプロパティのために1を書くことに終わる可能性があり

以上のような機能を繰り返す必要があるため必要があると思わよりもコードに時間がかかりますコントロール。

必ずしもいくつかの異なる方法でコードを単純化することはできますが、

Private Sub SetEnabled(ctrl As Control, value As Integer) 
    If ctrl.InvokeRequired Then 
     ctrl.Invoke(Sub() ctrl.Enabled = value) 
    Else 
     ctrl.Enabled = value 
    End If 
End Sub 

しかし、それを行うにしても簡単な方法は、実際にあります:たとえば、 TrackBarは、このようにあなたが機能を一般化することができ、 Controlクラスにキャストすることができることを意味する System.Windows.Forms.Controlから派生 Extension methods経由。呼び出しを自動的に実行する拡張メソッドと InvokeRequiredのチェックを作成することができます。その Sub() -lambda式はデリゲートに変換/キャストすることができ、あなたのメソッドの引数としてそれを使用しての意志でそれを呼び出すことができますへ

ありがとう:この拡張方法、で

Imports System.Runtime.CompilerServices 

Public Module Extensions 
    <Extension()> _ 
    Public Sub InvokeIfRequired(ByVal Control As Control, ByVal Method As [Delegate], ByVal ParamArray Parameters As Object()) 
     If Parameters IsNot Nothing AndAlso _ 
      Parameters.Length = 0 Then Parameters = Nothing 'If Parameters has a length of zero then no parameters should be passed. 
     If Control.InvokeRequired = True Then 
      Control.Invoke(Method, Parameters) 
     Else 
      Method.DynamicInvoke(Parameters) 
     End If 
    End Sub 
End Module 

ましたあなたは今、たとえば呼び出すことができるようになり、System.Windows.Forms.Controlから派生した任意のクラスを呼び出すことができます。

Me.InvokeIfRequired(Sub() TrackBar1.Enabled = True) 
'Me is the current form. I prefer to let the form do the invocation. 

これを持つことによって、あなたはまた、より長い文を呼び出すことができる:

Me.InvokeIfRequired(Sub() 
         Button1.Enabled = False 
         Label1.Text = "Something happened..." 
         ProgressBar1.Value += 5 
        End Sub) 
+0

なぜこれが下落したのですか?私は自分の経験から意見書を提出し、私は彼の質問に「これを行うより効率的な方法はありますか?」と答えました。 1つではなく、2つのかなり効率的なオプションで! –

+0

あなたは私の答えについて何でも思いたいかもしれません。しかし、あなたが私の答えが悪いと思うならば、Stack Overflowの投票システムの壁の後ろに隠れているので、少なくとも臆病者の行動に過ぎないので、少なくとも私に教えてください。 –

+0

おかげさまでVincent。スタックオーバーフローは時に厳しいものになる可能性がありますが、うまくいけば、私は答えを感謝し、私が探していたことのようなものだと分かっています。 – Nobody

関連する問題