|
I have a application that has a page that receives multiple packets from a TCP/IP server. Every time it receives it tries to run an event using Dispatcher.BeginInvoke which runs the event. The problem is that the event only runs on the first time Dispatcher.BeginInvoke. I believe that the reason for this is that because the thread is already running it can not be started again. Also, I have tried the Backgroundworker class and as soon as it hits my code I get an "Invalid cross thread access" error which makes me put the code back into the Silverlight Dispatcher.BeginInvoke and the origional problem occurs. How do I fix my problem?
Thanks,
Steve Holdorf
-- modified 25-Jan-13 7:06am.
|
|
|
|
|
Without seeing your code it is hard to say. I think the issue here is that you are using the Dispatcher.BeginInvoke which is actually saying, marshal any work onto the UI thread. what could be happening is that if you first action does not complete or blocks the UI then subsequent events may not bubble up to the UI thread which would not show anything.
You were right in trying another thread. Firstly do your work on another thread. At the point of updating the UI, put that bit in the Dispatcher call. So what you are saying is: Do my work on another thread. Once it is complete and I want to update my UI, marshal it onto the UI thread using the dispatcher.
|
|
|
|
|
It is hard for me to cut and paste code because I develop on one network and access the internet on another. But my code looks something like this:
Backgroundworker bw = new Backgroundworker();
public void Constructor ()
{
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
}
private void Update()
{
bw.bw_DoWorkAsync();
while (!autoEvent.WaitOne())
{
Dispatcher.BeginInvoke(timeline.UpdateEvents)
}
}
private void bw_DoWork(Object sender, DoWorkEventArgs e)
{
Dispatcher.beginInvoke(GetFreshData);
// This event is where I refresh the collection data
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Dispatcher.BeginInvoke(timeline.UpdateEvents)
//updates the timeline control where my refreshed collecton exists
}
Now, I put a break point in the bw_DoWork and bw_RunWorkerComplete which gets hit every time; however, the timeline control refresh never occurs except for the first time.
Thanks,
Steve Holdorf
-- modified 27-Jan-13 19:17pm.
|
|
|
|
|
What is the Do work complete? also what does the timeline.UpdateEvents do?
Are you using MVVM? I dont think so looking at the code you supplied but just wondered what the actual dataset was that the UI binds too?
|
|
|
|
|
Please remember that the actual code is at my office at work and I am at home. I have network security rules that don't allow me to bring code home. However, this is a Silverlight page control the Do Work Complete bw_RunWorkerCompleted is the Async event that is called once the bw_DoWork is finishes. Now, 'TimeLine timeline' is a codeplex control which is a sub-control on the main page control that displays a Silverlight timeline. How it works is that a wcf call is made which fills the timeline's List<Event> events collection that is a property of the TimeLine control. Now, when timeline.UpdateEvents is called the timeline control iterates the list and re-draws the timeline with each of the collection's event objects. The Backgroundworker class provides an Async run event and on event complete combination. I have to put the 'while (!autoEvent.WaitOne())', sorry I forgot the while in the while loop, to wait until the main thread signals so that the Dispatch.BeginInvoke(timeline.UpdateEvents) is blocked unitl the collection is updated by the wcf call or I get an exception. I know that my discription is a bit sketchy but this is all I can go on as far a specifics until in the morning. If you can help that would be great!
Thanks,
Steve Holdorf
-- modified 27-Jan-13 20:31pm.
|
|
|
|