Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在WPF中使用ISynchronizeInvoke接口?_C#_Wpf_Winforms_Thread Synchronization - Fatal编程技术网

C# 如何在WPF中使用ISynchronizeInvoke接口?

C# 如何在WPF中使用ISynchronizeInvoke接口?,c#,wpf,winforms,thread-synchronization,C#,Wpf,Winforms,Thread Synchronization,我有一个这样的组件,无法更改: public sealed class UFScannerManager { public UFScannerManager(ISynchronizeInvoke synInvoke); public ScannerList Scanners { get; } public event UFS_SCANNER_PROC ScannerEvent; public UFS_STATUS Init(); public UFS_S

我有一个这样的组件,无法更改:

public sealed class UFScannerManager
{
    public UFScannerManager(ISynchronizeInvoke synInvoke);
    public ScannerList Scanners { get; }
    public event UFS_SCANNER_PROC ScannerEvent;

    public UFS_STATUS Init();
    public UFS_STATUS Uninit();
    public UFS_STATUS Update();

    [DefaultMember("Item")]
    public sealed class ScannerList
    {
        public ScannerList(UFScannerManager Owner);

        public UFScanner this[int Index] { get; }
        public UFScanner this[string ScannerID] { get; }
        public UFScanner this[IntPtr ScannerHandle] { get; }

        public int Count { get; }
    }
}
我想创建如下组件的实例:
UFScannerManager(this)
,但在WPF中,我不能将pass
this
作为参数调用。这里的
this
表示当前窗口窗体对象,构造函数需要一个
ISynchronizeInvoke sysInvoke
参数。因此,当传递
时,扫描仪可以在Windows窗体应用程序中正确初始化。无需担心
ISynchronizeInvoke
接口

UFS_STATUS ufs_res;
UFScannerManager ScannerManager;
int nScannerNumber;
ScannerManager = new UFScannerManager(this);
ufs_res = ScannerManager.Init();
nScannerNumber = ScannerManager.Scanners.Count;
但是,此代码在WPF中不起作用。问题是这条线。它不喜欢的位是

ScannerManager = new UFScannerManager(this);
当我尝试构建时,我得到一个错误:

参数1:无法从“win_myapp”转换为“System.ComponentModel.ISynchronizeInvoke”


WPF不像
System.Windows.Forms.Form
类那样提供
ISynchronizeInvoke
实现。所以你需要创建一个

幸运的是,WPF的
Dispatcher
类提供了实现该功能所需的所有方法。您只需为
调度程序
调度程序操作
创建包装器/适配器

我可以告诉你怎么做。请注意,此代码不应“按原样”在生产环境中使用,因为它简化了,并且缺少异常处理

class DispatcherSynchronizeInvoke : ISynchronizeInvoke
{
    private readonly Dispatcher dispatcher;

    public DispatcherSynchronizeInvoke(Dispatcher dispatcher)
    {
        this.dispatcher = dispatcher;
    }

    public IAsyncResult BeginInvoke(Delegate method, object[] args)
    {
        // Obtaining a DispatcherOperation instance
        // and wrapping it with our proxy class
        return new DispatcherAsyncResult(
            this.dispatcher.BeginInvoke(method, DispatcherPriority.Normal, args));
    }

    public object EndInvoke(IAsyncResult result)
    {
        DispatcherAsyncResult dispatcherResult = result as DispatcherAsyncResult;
        dispatcherResult.Operation.Wait();
        return dispatcherResult.Operation.Result;
    }

    public object Invoke(Delegate method, object[] args)
    {
        return dispatcher.Invoke(method, DispatcherPriority.Normal, args);
    }

    public bool InvokeRequired => !this.dispatcher.CheckAccess();

    // We also could use the DispatcherOperation.Task directly
    private class DispatcherAsyncResult : IAsyncResult
    {      
        private readonly IAsyncResult result;

        public DispatcherAsyncResult(DispatcherOperation operation)
        {
            this.Operation = operation;
            this.result = operation.Task;
        }

        public DispatcherOperation Operation { get; }

        public bool IsCompleted => this.result.IsCompleted;
        public WaitHandle AsyncWaitHandle => this.result.AsyncWaitHandle;
        public object AsyncState => this.result.AsyncState;
        public bool CompletedSynchronously => this.result.CompletedSynchronously;
    }
}
使用此自定义
ISynchronizeInvoke
实现,您可以实例化您的类:

// Assuming you're calling this inside of a DispatcherObject, e.g. a Window
new UFScannerManager(new DispatcherSynchronizeInvoke(this.Dispatcher));

接口的优点是可以编写任意类来实现它。接口的方法很容易映射到WPF调度程序:Invoke=>Invoke,BeginInvoke=>BeginInvoke,EndInvoke=>dispatcherooperation.Wait(),InvokeRequired=>CheckAccess。