如何从新线程传递数据
本文关键字:数据 线程 新线程 | 更新日期: 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
}