Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.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# ExcelDna:Async:调用线程必须是STA_C#_Excel Dna - Fatal编程技术网

C# ExcelDna:Async:调用线程必须是STA

C# ExcelDna:Async:调用线程必须是STA,c#,excel-dna,C#,Excel Dna,我正在使用ExcelDna和异步函数。如果async:d代码中有异常,我想显示一个奇特的WPF错误窗口。我的问题是,我得到了一个错误,调用线程必须是STA,因为许多UI组件都需要它。我怎样才能解决这个问题 [ExcelFunction(Description = "", Category = "")] public static async Task<object> /*string*/ Foo(CancellationToken ct) {

我正在使用ExcelDna和异步函数。如果async:d代码中有异常,我想显示一个奇特的WPF错误窗口。我的问题是,我得到了一个错误,调用线程必须是STA,因为许多UI组件都需要它。我怎样才能解决这个问题

    [ExcelFunction(Description = "", Category = "")]
    public static async Task<object> /*string*/ Foo(CancellationToken ct)
    {
        try
        {
            return await Task.Run(async () =>
            {
                await Task.Delay(1000, ct);
                throw new Exception("BOO");
                return "HelloWorld";
            }, ct2.Token);
        }
        catch (Exception e)
        {
            return ShowWpfErrorWindowThatRequiresSTA(e);
        }
    }

许多Office插件都存在SynchronizationContext.Current为null,并且异步continuations在线程池上执行的问题。我会在第一次等待之前检查SynchronizationContext.Current的值


我已经成功地创建了WinFormsSynchronizationContext,并在第一次等待之前将其安装到线程上。但是,安装WPF上下文将更加复杂。

许多Office插件在SynchronizationContext.Current为null,并且在线程池上执行异步continuations时存在问题。我会在第一次等待之前检查SynchronizationContext.Current的值


我已经成功地创建了WinFormsSynchronizationContext,并在第一次等待之前将其安装到线程上。但是,安装WPF上下文将更为复杂。

当Excel函数运行时,没有SynchronizationContext。当前已安装,因此异步/等待机制将在等待后运行代码,包括线程池线程上的捕获处理程序。这不是一个可以直接显示WPF表单的上下文

安装与在主线程或另一个线程上运行的调度程序相对应的DispatcherSynchronizationContext是可行的,但是对于每个UDF调用,您都必须这样做。不知何故,通过Excel的本机代码路径会丢失主线程上的.NET调用上下文,因此SynchronizationContext会丢失

更好的方法可能是假设catch处理程序正在线程池线程上运行,并从catch处理程序发出SynchronizationContext.Post调用,将您带回运行Dispatcher和WPF表单的主线程

您可以查看Excel DNA如何实现WinForms LogDisplay窗口。你可以调用LogDisplay.WriteLine。。。它将执行一个_syncContext.Post来在主线程上运行“Show”


C async/await机制在Excel中的效果不太好,因为本机/托管转换以及Excel内部执行的任何操作都会弄乱需要在延续之间流动的线程上下文。即使在.NET方面,也不清楚AppDomains和不同Excel加载项之间如何管理线程上下文。因此,最好不要依赖.NET运行时能够通过托管/本机转换执行任何类型的上下文。

当Excel函数运行时,没有SynchronizationContext。当前已安装,因此async/await机制将在await之后运行代码,包括线程池线程上的catch处理程序。这不是一个可以直接显示WPF表单的上下文

安装与在主线程或另一个线程上运行的调度程序相对应的DispatcherSynchronizationContext是可行的,但是对于每个UDF调用,您都必须这样做。不知何故,通过Excel的本机代码路径会丢失主线程上的.NET调用上下文,因此SynchronizationContext会丢失

更好的方法可能是假设catch处理程序正在线程池线程上运行,并从catch处理程序发出SynchronizationContext.Post调用,将您带回运行Dispatcher和WPF表单的主线程

您可以查看Excel DNA如何实现WinForms LogDisplay窗口。你可以调用LogDisplay.WriteLine。。。它将执行一个_syncContext.Post来在主线程上运行“Show”


C async/await机制在Excel中的效果不太好,因为本机/托管转换以及Excel内部执行的任何操作都会弄乱需要在延续之间流动的线程上下文。即使在.NET方面,也不清楚AppDomains和不同Excel加载项之间如何管理线程上下文。因此,最好不要依赖.NET运行时能够在托管/本机转换中执行任何类型的上下文。

可能的副本必须在UI线程上显示一个窗口。使用Application.Current.Dispatcher.BeginInvoke.mable duplicate的mable duplicate的mable duplicate必须在UI线程上显示一个窗口。使用Application.Current.Dispatcher.BeginInvoke.Works的可能副本!我创建了一个静态WindowsFormsSynchronizationContext似乎也适用于WPF?在我的AutoOpen中,我在HandleError内部使用它。你怎么说它不会粘住?你会怎么做?很有效!我创建了一个静态WindowsFormsSynchronizationContext似乎也适用于WPF?在我的AutoOpen中,我在HandleError内部使用它。你怎么说它不会粘住?你会怎么做?