不应该属性时,依赖属性的SetValue抛出异常。 [英] Dependency property's SetValue throws exception when not supposed to.

查看:86
本文介绍了不应该属性时,依赖属性的SetValue抛出异常。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

各位大家好。我的问题是这样的:

我有一个DependencyProperty,当在正确的线程上设置时(Dispatcher.CheckAccess返回true)抛出InvalidOperationException(调用线程无法访问此对象,因为另一个线程拥有它。)。



  public   static   class  PicGetter 
{
public static ConcurrentQueue< TFileInfo> cq = new ConcurrentQueue< TFileInfo>();

public static void GetPix()
{
Thread tron = new Thread(_GetPix);
tron.Name = Thumb obtaininer;
tron.IsBackground = true ;
tron.Start();
}

public static void _GetPix()
{
TFileInfo f;
while (!cq.IsEmpty)
{
if ( cq.TryDequeue( out f))
f.Thu();
}
}

public static void Thu( this TFileInfo f)
{
BitmapSource bs;
if (Misc.Windows7)
{
ShellFile sf = ShellFile.FromFilePath(f.FullName);
bs = sf.Thumbnail.ExtraLargeBitmapSource;
}
else if (f.isPic())
bs = new 位图(Image.FromFile(f.FullName))。ToBitmapSource();
else
bs = Icon.ExtractAssociatedIcon(f.FullName)。ToBitmap()。ToBitmapSource();

f.Dispatcher.Invoke( new Action< BitmapSource,TFileInfo>((b,t)= > t.Thumb = b),bs,f);
}
}

public class TFileInfo: DependencyObject
{
public BitmapSource Thumb
{
get { return (BitmapSource)GetValue(ThumbProperty); }
set
{
// MessageBox.Show(Dispatcher.CheckAccess()+\ n+ this.Dispatcher.Thread.ManagedThreadId +\ n+ Thread.CurrentThread.ManagedThreadId);
SetValue(ThumbProperty, value ); }
}
public static readonly DependencyProperty ThumbProperty =
DependencyProperty.Register(
Thumb
typeof (BitmapSource),
typeof (TFileInfo),
new UIPropertyMetadata(( new 位图(Assembly.GetExecutingAssembly()。GetManifestResourceStream( BiblioRap.Images.BlankDoc.png)))。BitmapSource()));
}





我不能为我的生活弄明白为什么会这样做。异常的堆栈跟踪结束于System.Windows.Threading.Dispatcher.VerifyAccess()。

解决方案

属性 System.Windows.Threading .Dispatcher.CheckAccess 只告诉你调用线程是与 this Dispatcher关联的线程(调用者的实例在调用此实例属性)。它不会告诉您可以从此线程访问UI方法/属性 - 如果这不是运行相同UI的线程,您永远不能



调度员的目的是什么?要使UI在UI线程中调用某个委托,通过 Dispatcher.Invoke Dispatcher.BeginInvoke



您无法从非UI线程调用与UI相关的任何内容。相反,您需要使用 Invoke System.Windows.Threading的方法。 Dispatcher (对于Forms或WPF)或 System.Windows.Forms.Control (仅限表单)。



您将在我过去的答案中找到有关其工作原理和代码示例的详细说明:

Control.Invoke()与Control.BeginInvoke() [ ^ ],

使用Treeview扫描仪和MD5的问题 [ ^ ]。



另请参阅有关线程的更多参考资料:

如何让keydown事件在不同的操作上运行vb.net中的线程 [ ^ ],

在启用禁用+多线程后控制事件未触发 [ ^ ]。



-SA


您好Claudiu,

我在这个页面的回答是否可以帮助您:

http://www.codeproject.com/Answers/409837/Creating-trace-log-file-using-threading#answer4



祝你好运



即使这个问题是四r岁...



尝试在使用之前冻结位图。



参见: this.Dispatcher.Invoke给我调用线程无法访问此对象,因为另一个线程拥有它 [ ^ ]



和: Freezable.Freeze方法(System.Windows) [ ^ ]


Hello everybody. My problem goes like this:
I have a DependencyProperty, which when set while on the correct thread (Dispatcher.CheckAccess returns true) throws an InvalidOperationException ("The calling thread cannot access this object because a different thread owns it.").

public static class PicGetter
{
    public static ConcurrentQueue<TFileInfo> cq = new ConcurrentQueue<TFileInfo>();

    public static void GetPix()
    {
        Thread tron = new Thread(_GetPix);
        tron.Name = "Thumb obtainer";
        tron.IsBackground = true;
	tron.Start();
    }

    public static void _GetPix()
    {
	TFileInfo f;
	while (!cq.IsEmpty)
	{
            if (cq.TryDequeue(out f))
		f.Thu();
	}
    }

    public static void Thu(this TFileInfo f)
    {
	BitmapSource bs;
	if (Misc.Windows7)
	{
            ShellFile sf = ShellFile.FromFilePath(f.FullName);
            bs = sf.Thumbnail.ExtraLargeBitmapSource;
	}
	else if (f.isPic())
	    bs = new Bitmap(Image.FromFile(f.FullName)).ToBitmapSource();
	else
	   bs = Icon.ExtractAssociatedIcon(f.FullName).ToBitmap().ToBitmapSource();

        f.Dispatcher.Invoke(new Action<BitmapSource, TFileInfo>((b, t) => t.Thumb = b), bs, f);
    }
}

public class TFileInfo : DependencyObject
{
    public BitmapSource Thumb
    {
	get { return (BitmapSource)GetValue(ThumbProperty); }
	set
	{
	    //MessageBox.Show(Dispatcher.CheckAccess() + "\n" + this.Dispatcher.Thread.ManagedThreadId + "\n" + Thread.CurrentThread.ManagedThreadId);
	    SetValue(ThumbProperty, value); }
	}
    public static readonly DependencyProperty ThumbProperty =
	DependencyProperty.Register(
	"Thumb",
	typeof(BitmapSource),
	typeof(TFileInfo),
	new UIPropertyMetadata((new Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream("BiblioRap.Images.BlankDoc.png"))).BitmapSource()));
}



I cannot for the life of me figure out why it does so. The exception's stack trace ends "at System.Windows.Threading.Dispatcher.VerifyAccess()".

解决方案

The property System.Windows.Threading.Dispatcher.CheckAccess only tells you that the calling thread is the thread associated with this Dispatcher (the instance of the dispatcher used as "this" in the call of this instance property). It does not tell you that you can access UI methods/properties from this thread — if this is not the thread running the same UI, you never can.

What do you thing is the purpose of the dispatcher? To cause the UI to call some delegate in the UI thread, through Dispatcher.Invoke or Dispatcher.BeginInvoke.

You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA


Hi Claudiu,
Does my answer at this page help you :
http://www.codeproject.com/Answers/409837/Creating-trace-log-file-using-threading#answer4

Good Luck


Hi,
even if this question is four years old ...

Try to freeze the bitmap before using it.

See also: this.Dispatcher.Invoke gives me "The calling thread cannot access this object because a different thread owns it"[^]

and: Freezable.Freeze Method (System.Windows)[^]


这篇关于不应该属性时,依赖属性的SetValue抛出异常。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆