Ошибка потока WPF STA - PullRequest
       9

Ошибка потока WPF STA

0 голосов
/ 17 октября 2011

Я следую коду, указанному в этой теме C # Async WebRequests: выполнить действие после завершения всех запросов

В моем приложении WPF мне нужно асинхронно загружать изображения с сервера. Однако я получаю следующую ошибку

The calling thread must be STA, because many UI components require this.

Может быть, потому что я делаю обновления пользовательского интерфейса в основном потоке? Я также объявил состояние вызывающего потока в STA, мой код выглядит следующим образом:

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

Пожалуйста, кто-нибудь может помочь?

Большое спасибо

Ответы [ 2 ]

0 голосов
/ 17 октября 2011

Вы можете попробовать обернуть ваш код ниже, однако это грязное решение.

MyUIElement.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
{

    //your code here

}));

лучше всего, если MyUIElement был вашим верхним окном.

0 голосов
/ 17 октября 2011

Вам нужно вызывать каждую операцию пользовательского интерфейса в MainThread, я думаю, ваш метод UpdateItem не будет вызываться в потоке пользовательского интерфейса, поэтому вы получите это исключение.

я бы изменил 2 вещи:

Во-первых, используйте класс BackgroundWorker , что значительно упрощает асинхронные операции в WPF.

Во-вторых, если у вас есть другой поток (Backgroundworker или пользовательский поток), вы всегда должны отправлять каждую операцию пользовательского интерфейса в основной поток.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...