WPF STA 线程错误
我正在遵循此线程上给出的代码 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以尝试将代码包装在下面,但是这是肮脏的解决方案。
如果 MyUIElement 是您的顶部窗口,那就最好了。
You can try wrapping your code in below, this however is dirty solution.
best if MyUIElement was your top window.
您需要调用 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.