调用线程不能访问此对象,因为不同的线程拥有它
好吧,我当前的代码正在进行中,可能我会尝试使用Async CTP做同样的事情。但我仍然想知道发生了什么。调用线程不能访问此对象,因为不同的线程拥有它
我有HttpHelper
@pastebin像下面
// In MainWindow.xaml.cs
Task.Factory.StartNew(() => helper.Send());
// In class HttpHelper
public void Send()
{
// ...
try
{
Status = Statuses.Uploading;
// write to request stream
Status = Statuses.Downloading;
// write to response stream
Status = Statuses.Idle; // the exception is thrown here
// ...
}
catch (Exception e)
{
// ...
}
}
完整的代码的功能。 Send()
on line 76
我想知道为什么我会得到异常?也许我在线程方面做了一些错误,但为什么只有在成功设置Status
属性两次后才会引发异常?
UPDATE:原因...
我有一个事件处理程序,听StatusChanged
事件,在1 if语句,我忘了使用UI线程更新UI
helper.StatusChanged += (s, evt) =>
{
_dispatcher.Invoke(new Action(() => txtStatus.Text = helper.Status.ToString())); // I used _dispatcher here correctly
if (helper.Status == HttpHelper.Statuses.Idle || helper.Status == HttpHelper.Statuses.Error)
progBar.IsIndeterminate = false; // but not here
};
更新:我错过了(在我的防守,小)在您的代码中的评论,你放弃了使用WPF/Silverlight而不是Windows窗体。
不过,看起来你能够采取什么我说的基本精神,并将其应用到自己的情况适当地(使用Dispatcher.Invoke
而不是Control.Invoke
)-Well完成;)
我猜测附加到您的StatusChanged
事件的事件处理程序会更新您的UI上的StatusLabel
控件?如果是这种情况,那么你需要从UI线程调用Invoke
;例如:
void HttpHelper_StatusChanged(object sender, EventArgs e)
{
var httpHelper = (HttpHelper)sender;
UpdateStatus(httpHelper.Status);
}
void UpdateStatus(HttpHelper.Statuses status)
{
if (InvokeRequired)
{
Invoke(new Action<HttpHelper.Statuses>(UpdateStatus), status);
}
else
{
// Your code probably doesn't look like this;
// it's just an example.
statusLabel.Text = status.ToString();
}
}
你可能会看到两个成功后跟一个失败的原因有点超出我的意思;但我知道StatusLabel
控件在涉及线程问题时尤其会有点回避。我已经看到代码在哪里直接从后台线程更新(通常由于开发人员的疏忽)而没有任何异常;它看起来像你刚刚幸运两次,不幸一次。
虚拟-1。没有!!它是Dispatcher.Invoke()。这是WPF/SilverLight不是WPF。 – Aliostad 2010-11-22 13:48:41
@Aliostad:好的呼叫;在这种情况下,我认为我看到了问题。我会更新(再次)... – 2010-11-22 13:53:18
@Aliostad:呃... OP太聪明了,知道了。这让我的生活更轻松;) – 2010-11-22 14:00:02
如果Status是一个全局变量,你将会得到这个异常,因为多个线程同时访问和更新它。我建议使用它附近的锁
Status
是否触摸用户界面?因为它看起来像。
我只能猜测,但我想Status
改变了UI上需要通过Dispatcher.Invoke()
完成的事情。
因为有时你会得到UI线程,有时你不会...... – 2010-11-22 13:41:14