WPF STA线程错误

时间:2011-10-17 13:13:05

标签: wpf multithreading asynchronous httpwebrequest

我正在关注此帖子C# Async WebRequests: Perform Action When All Requests Are Completed

上提供的代码

在我的WPF应用程序中,我需要从服务器异步下载图像。但是我收到以下错误

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

可能是因为我在主线程上进行UI更新吗?我还将调用线程的状态声明为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 :(得分:0)

你需要在MainThread中调用每个UI操作,我猜你的UpdateItem方法不会在UI线程中被调用,因此你会得到这个例外。

我会改变两件事:

首先,使用BackgroundWorker类,这使得WPF中的这种异步操作变得更简单。

其次,如果你有另一个线程(Backgroundworker或自定义线程),你总是必须Dispatch每个UI操作进入主线程。

答案 1 :(得分:0)

你可以尝试在下面包装你的代码,但这是一个肮脏的解决方案。

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

    //your code here

}));
如果MyUIElement是你的首选窗口,那么

最好。