【问题标题】:WPF STA thread errorWPF STA 线程错误
【发布时间】:2011-10-17 13:13:05
【问题描述】:

我正在关注这个线程上给出的代码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;  
    }

有人可以帮忙吗?

非常感谢

【问题讨论】:

  • 另外,调用t.Join()会阻塞UI线程
  • UpdateItem 在线程池线程上运行,它们始终是 MTA。但是将工作线程设置为 STA 无论如何也无济于事,这是错误的单线程单元。您必须使用 Dispatcher.Begin/Invoke() 来创建图像。

标签: wpf multithreading asynchronous httpwebrequest


【解决方案1】:

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

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

    //your code here

}));

如果 MyUIElement 是您的顶部窗口最好。

【讨论】:

    【解决方案2】:

    您需要在 MainThread 中调用每个 UI 操作,我猜您的 UpdateItem 方法不会在 UI 线程中调用,因此您会收到此异常。

    我会改变两件事:

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

    其次,如果您有另一个线程(Backgroundworker 或自定义线程),您始终必须 Dispatch 对主线程的每个 UI 操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多