I am following the code given on this thread C# Async WebRequests: Perform Action When All Requests Are Completed
In my WPF app I need to asynchronously download images from the server. However I get the following error
The calling thread must be STA, because many UI components require this.
Could it be because I am doing UI updates on the main thread? I have also declared the calling thread’s state to STA, my code follows:
private void FixedDocument_Loaded(object sender, RoutedEventArgs e)
{
Thread t = new Thread(new ThreadStart(AsyncLoadImages));
t.IsBackground = true;
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
}
private void AsyncLoadImages()
{
foreach (string resFile in resFiles)
{
string imageuri = @"http://www.example.com/image.jpg";
WebRequest request = HttpWebRequest.Create(imageuri);
request.Method = "GET";
object data = new object();
RequestState state = new RequestState(request, data);
IAsyncResult result = request.BeginGetResponse(
new AsyncCallback(UpdateItem), state);
ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, new WaitOrTimerCallback(ScanTimeoutCallback), state, (30 * 1000), true);
}
}
private static void ScanTimeoutCallback(object state, bool timedOut)
{
if (timedOut)
{
RequestState reqState = (RequestState)state;
if (reqState != null)
{
reqState.Request.Abort();
}
Console.WriteLine("aborted- timeout");
}
}
private void UpdateItem(IAsyncResult result)
{
RequestState state = (RequestState)result.AsyncState;
WebRequest request = (WebRequest)state.Request;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = response.GetResponseStream();
bi.EndInit();
Image i = new Image(); //hitting the error at this line
i.Source = bi;
}
Please can someone help?
Many Thanks
You need to call every UI operation in the MainThread i guess your UpdateItem method will not be called in the UI Thread thus you get this exception.
i would change 2 things:
First, use the BackgroundWorker class, which makes this kind of async operations in WPF alot simpler.
Second, if you have another thread (Backgroundworker or custom Thread) you always must Dispatch every UI operation into the main thread.