0

私は、非同期のtcp操作から入ったイベントデータを使用して提供するライブラリを持っています。 UI上で受け取ったコントロールのデータを使用しているのに、クロススレッドOpration例外が発生します。ライブラリの消費者が自分のコントロールに表示するデータを取得する前に、この問題を解決する方法。だから基本的に私は自分のスレッドにライブラリを使ってどこにデータを投げる必要がありますか?他のスレッドからのデータを安全にコントロールするにはどうすればいいですか?

リンクされたファイルでコンパクトなフレームワークに使用されているのと同じコード。

私はこのメソッドをヘルプコントロールでライブラリ内で使用していますが、呼び出しが必要ではあるが動作していないと言っています。

イベントを使用してライブラリを使用するユーザーにデータを提供するサンプルコードです。

if (OnClientChangeConnection != null) SafeData.InvokeIfNecessary(_helpControl,() => OnClientChangeConnection(ConnectedClients, requestClientInfo)); // ConnectedClients is an integer and requestClientInfo is a List<ClientInfo> class type. 

ありがとうございます。

+0

を持つクラスですか?何が起こるのですか? – SLaks

+0

私もそれを取得しません、それはちょうどcontrol.Invoke(setValue)になることはありません。このライブラリは、非同期TCP通信の目的で使用されます。 StrangeはCompact Frameworkにあります私は問題ありません。 –

+0

デバッガには何が表示されますか? – SLaks

答えて

0

SynchronizationContext.Currentへの参照をUIスレッドから保存してから、そのPostまたはSendメソッドを呼び出すと、UIスレッドでコードを実行できます。

1

これを行う適切な方法は、SynchronizationContextオブジェクトを使用することです。サンプルコードが含まれています。あなたがしなければならないことは、メインスレッドが提供する同期コンテキストオブジェクトとコールバックへの参照を保存できるクラスにスレッドタスクをラップすることです。

これは単純な形式である:

public partial class Form1 : Form 
{ 
    private SynchronizationContext _synchronizationContext; 

    public Form1() 
    { 
     InitializeComponent(); 
     //Client must be careful to create sync context soimehwere they are sure to be on main thread 
     _synchronizationContext = AsyncOperationManager.SynchronizationContext; 
    } 

    //Callback method implementation - must be of this form 
    public void ReceiveThreadData(object threadData) 
    { 
     // Can use directly in UI without error 
     this.listBoxMain.Items.Add((string)threadData); 
    } 

    private void DoSomeThreadWork() 
    { 
     // Thread needs callback and sync context. 
     // You probably want to derive your own callback from the NET SendOrPostCallback class. 
     SendOrPostCallback callback = new SendOrPostCallback(ReceiveThreadData); 
     SomeThreadTask task = new SomeThreadTask(_synchronizationContext, callback); 
     Thread thread = new Thread(task.ExecuteThreadTask); 
     thread.Start(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     DoSomeThreadWork(); 
    } 

} 

これは、それが動作しないのはなぜスレッドタスク

/// SomeThreadTask defines the work a thread needs to do and also provides any data required along with callback pointers etc. 
/// Populate a new SomeThreadTask instance with a synch context and callnbackl along with any data the thread needs 
/// then start the thread to execute the task. 
/// </summary> 
public class SomeThreadTask 
{ 

    private string _taskId; 
    private SendOrPostCallback _completedCallback; 
    private SynchronizationContext _synchronizationContext; 

    /// <summary> 
    /// Get instance of a delegate used to notify the main thread when done. 
    /// </summary> 
    internal SendOrPostCallback CompletedCallback 
    { 
     get { return _completedCallback; } 
    } 

    /// <summary> 
    /// Get SynchronizationContext for main thread. 
    /// </summary> 
    internal SynchronizationContext SynchronizationContext 
    { 
     get { return _synchronizationContext; } 
    } 

    /// <summary> 
    /// Thread entry point function. 
    /// </summary> 
    public void ExecuteThreadTask() 
    { 

     //Just sleep instead of doing any real work 
     Thread.Sleep(5000); 

     string message = "This is some spoof data from thread work."; 

     // Execute callback on synch context to tell main thread this task is done. 
     SynchronizationContext.Post(CompletedCallback, (object)message); 


    } 

    public SomeThreadTask(SynchronizationContext synchronizationContext, SendOrPostCallback callback) 
    { 
     _synchronizationContext = synchronizationContext; 
     _completedCallback = callback; 
    } 

} 
+0

あなたの時間をありがとう、これは良い解決策を見て、私は最初の答えとしてマークし、何とかいくつかのクレジットを共有するようにポイントを与える。あなたより –

関連する問題