如何从新线程传递数据

本文关键字:数据 线程 新线程 | 更新日期: 2023-09-27 18:14:00

我有一个类:

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();
        }
    }
}

在我的主线程中,我创建ShowComboBoxUpdater并将事件ResultUpdate连接到其他事件。然后我调用RequestUpdatingComboSource()方法。我已经激活了我的事件,但是,我如何才能得到结果serverQueryResult ?我知道它在那里,但我尝试的一切结果例外,我想要得到的是"owned by other thread"

如何从新线程传递数据

如何通过价值?

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中更新值时进行指示。在捕获的SynchronizationContext引用上发送/Post方法,以便将消息推送到UI线程中。

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 
        }