2011-11-09 4 views
0

私はクラスを持っている:私はShowComboBoxUpdaterを作成し、他のイベントにイベントResultUpdateを接続して、私のメインスレッドで新しいスレッドからデータを渡すには?

class ShowComboBoxUpdater 
{ 
    private ComboBox _showComboBox; 
    private String _searchString; 
    private RequestState _endState; 

    public event EventHandler ResultUpdated; 

    public string[] getShowList() 
    { 
     if (_endState.serverQueryResult != null) 
      return _endState.serverQueryResult; 
     return new string[] { "" }; 
    } 

    public ShowComboBoxUpdater(ComboBox combo, Image refreshImage) 
    { 
     _showComboBox = combo; 
     _refreshImage = refreshImage; 
     _endState = new RequestState(); 
    } 

    public void RequestUpdatingComboSource() 
    { 
     _searchString = _showComboBox.Text; 
     Thread t = new Thread(new ThreadStart(MakeServerConnectionThread)); 
     t.IsBackground = true; 
     t.Start(); 
    } 

    private void MakeServerConnectionThread() 
    { 
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://services.tvrage.com/myfeeds/search.php?show=" + _searchString); 
     _endState.request = request; 
     IAsyncResult result = request.BeginGetResponse(new AsyncCallback(RequestingThread), _endState); 
     ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, new WaitOrTimerCallback(ScanTimeoutCallback), _endState, (30 * 1000), true); 
    } 

    private void RequestingThread(IAsyncResult result) 
    { 
     RequestState state = (RequestState)result.AsyncState; 
     WebRequest request = (WebRequest)state.request; 

     HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result); 
     Stream bodyStream = response.GetResponseStream(); 
     StreamReader r = new StreamReader(bodyStream); 
     string xmlResponse = r.ReadToEnd().Trim(); 

     using (StringReader XMLStream = new StringReader(xmlResponse)) 
     { 
      XPathNavigator feed = new XPathDocument(XMLStream).CreateNavigator(); 
      XPathNodeIterator nodesNavigator = (XPathNodeIterator)feed.Evaluate("descendant::show/name/text()"); 
      int titlesCount = nodesNavigator.Count; 
      string[] titles = new string[titlesCount]; 
      foreach (XPathNavigator n in nodesNavigator) 
      { 
       titles[--titlesCount] = n.Value; 
      } 
      state.serverQueryResult = titles; 
      if (this.ResultUpdated != null) this.ResultUpdated(this, new EventArgs()); 
     } 
    } 

    private static void ScanTimeoutCallback(object state, bool timedOut) 
    { 
     if (timedOut) 
     { 
      RequestState reqState = (RequestState)state; 
      if (reqState != null) 
       reqState.request.Abort(); 
     } 
    } 
} 

。それから私はRequestUpdatingComboSource()メソッドを呼んでいます。イベントをアクティブにしましたが、どうすれば結果が得られますかserverQueryResult?私はそれがそこにあることを知っているが、私が得たいものが"owned by other thread"であることを除いて、私が試したすべての結果が出る。

+1

使用control.Dispatched.Invoke/BeginInvokeをマーシャルにUIスレッド –

+0

へのお電話は、あなたがスレッドtによって生成される結果を取得したいですか? – Tudor

答えて

0

どのように値を渡すか?

public class MyArgs : EventArgs 
    { 
     //Declare any specific type here 
     public string ResultToPass { get; private set; } 
     public MyArgs() 
     { 
     } 
    } 

if (this.ResultUpdated != null) this.ResultUpdated(this, new MyArgs(){ResultToPass="Your actual result"}); 

どのように結果を更新するには?

UI(メインスレッド)のSynchronizationContextをキャプチャして、UIで値を更新して戻すように指示します。メッセージをUIスレッドにプッシュするために、キャプチャされたSynchronizationContext参照のSend/Postメソッド。

public partial class MainWindow : Window 
    { 
     SynchronizationContext UISyncContext; 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 
     public StartProcessing() 
     { 
      //Let say this method is been called from UI thread. i.e on a button click 
      //capture the current synchronization context 

      UISyncContext=TaskScheduler.FromCurrentSynchronizationContext; 
     }  
     public UpdateResultInUI() 
     { 
      //Let's say this is is the method which user triggers at 
      //some point in time (with the assumption that we have Myresult in hand) 

      if(UISyncContext!=null) 
       UISyncContext.Send(new SendOrPostCallback(delegate{ PutItInUI }),null); 

      //Use Send method - to send your request synchronously 
      //Use Post method- to send your request asynchronously 
     } 
     void PutItInUI() 
     { 
      //this method help you to put your result in UI/controls 
     } 
+0

「UISyncContext = TaskScheduler.FromCurrentSynchronizationContext;」を「UISyncContext = SynchronizationContext.Current;」に変更し、完全に動作します。どうもありがとうございました ! –

+0

それを知ってよかったです。 :) –

関連する問題