WPF STA 线程错误

发布于 2024-12-10 14:47:43 字数 2197 浏览 0 评论 0原文

我正在遵循此线程上给出的代码 C#异步 WebRequests:完成所有请求后执行操作

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

调用线程必须是 STA,因为许多 UI 组件都需要此。

可能是因为我正在主线程上进行 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;  
    }

请问有人可以帮忙吗?

非常感谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

メ斷腸人バ 2024-12-17 14:47:43

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

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

    //your code here

}));

如果 MyUIElement 是您的顶部窗口,那就最好了。

You can try wrapping your code in below, this however is dirty solution.

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

    //your code here

}));

best if MyUIElement was your top window.

彻夜缠绵 2024-12-17 14:47:43

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

我会改变两件事:

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文