在C++/CLI中,您无法创建托管lambda(就像在C#中一样),因此无法捕获托管变量.您可以创建常规方法(而不是lambdas),但仍然无法捕获托管变量.
是否有在C++/CLI代码中使用的标准解决方法?换句话说,我正在寻找一种可以在C++/CLI中使用的标准模式来从C#执行以下操作:
class A { }
class B
{
void Foo()
{
A a = new A();
Func<A> aFunc = () => a; // Captures a
}
}
Run Code Online (Sandbox Code Playgroud)
我可以
问题:是否有比上述更好的选择,或者上面哪个选项是您的首选方法?
相关问题:
如果我有一个无会话绑定,在任何情况下客户端通道都会出错吗?
在我的具体情况下,我有以下自定义绑定:
<customBinding>
<binding name="MyCustomBinding">
<mtomMessageEncoding/>
<httpTransport/>
</binding>
</customBinding>
Run Code Online (Sandbox Code Playgroud)
在客户端,我使用派生自的默认生成代理ClientBase<T>.
我期待如果服务抛出一个未处理的异常,FaultException那将导致通道出现故障,并使客户端代理也出错.但事实并非如此 - 代理仍处于开放状态,之后可以使用.我也试图违反Binding的一个超时 - 这也没有使通道出错并且客户端代理仍处于打开状态.
是否有任何情况会导致客户端代理出现故障?
有关:
我有一个C#库,希望能够发送/发布工作到"主"ui线程(如果存在).该库可用于:
在库中我想在初始化期间捕获一些东西(A SynchronizationContext,Dispatcher,Task Scheduler或其他东西),这将允许我(稍后)将发送/后期工作发送到主线程(如果主线程有这种能力 - 即它有一个消息泵).例如,当且仅当主应用程序能够访问主线程时,库才会在主线程上放置一些Winforms UI.
我试过的事情:
Dispatcher.Invoke从后台线程使用将挂起(如预期的那样).我可以使用Dispatcher.FromThread(如果不存在,则不会为该线程创建Dispatcher).但是本机UI应用程序将使用此方法返回null Dispatcher,因此我再次陷入困境,无法区分UI应用程序和控制台应用程序.当然,我可以让我的库的用户在调用我的Initialize方法时指定它是否是UI应用程序,但我希望尽可能避免对库的用户造成这种复杂化.
使用Winforms,如果我在一个不是"主要"ui线程的线程上,我可以安全地使用
看起来我会遵守以下规则:必须在创建它们的线程上修改Winforms控件.
从我已经完成的一些阅读中看来,ShowDialog似乎会创建自己的消息泵,这样我就不必担心在已经有消息泵的线程上创建Form.
问题的背景是我得到一个回调,我想显示一些Winforms UI,但我没有访问任何其他可以用来调用主线程的UI.
与此问题相关,
是await应该恢复的背景下(特别是通过上下文所代表Thread.CurrentContext的)ContextBoundObject?考虑以下内容:
class Program
{
static void Main(string[] args)
{
var c1 = new Class1();
Console.WriteLine("Method1");
var t = c1.Method1();
t.Wait();
Console.WriteLine("Method2");
var t2 = c1.Method2();
t2.Wait();
Console.ReadKey();
}
}
public class MyAttribute : ContextAttribute
{
public MyAttribute() : base("My") { }
}
[My]
public class Class1 : ContextBoundObject
{
private string s { get { return "Context: {0}"; } } // using a property here, since using a field causes things …Run Code Online (Sandbox Code Playgroud) 我正在尝试从转储中追踪NullReferenceException.NullReferenceException不是崩溃异常,而是崩溃异常是TargetInvocationException,其InnerException是NullReferenceException.
我正在使用带有SOS的Windbg,我使用该命令analyze -v,这给了我NullReferenceException的调用堆栈:
EXCEPTION_OBJECT: !pe f6cb150
Exception object: 000000000f6cb150
Exception type: System.NullReferenceException
Message: Object reference not set to an instance of an object.
InnerException: <none>
StackTrace (generated):
SP IP Function
000000002CD9D8C0 000007FF01E7C639 MyDll!DoSomething2()+0xe99
000000002CD9DBE0 000007FF01E7B11D MyDll!DoSomething1()+0x43d
000000002CD9DD20 000007FF01E7AB11 MyDll!WorkerDoWork(System.Object, System.ComponentModel.DoWorkEventArgs)+0x51
000000002CD9DD80 000007FEEA68A0F2 System_ni!System.ComponentModel.BackgroundWorker.WorkerThreadStart(System.Object)+0x62
Run Code Online (Sandbox Code Playgroud)
请注意,我得到了具有字节偏移的方法名称,但没有行号. DoSomething2是一个很大的函数,因此NullReferenceException发生的位置并不明显.
我试图按照Tess Ferrandez博客中的说明操作:
但是我很早就陷入困境,我尝试DoSomething2使用!ip2md和DoSomething2:7FF01E7C639的IP 来确定方法的方法描述符:
> !ip2md 7FF01E7C639
Failed to request MethodData, not in JIT code range
Run Code Online (Sandbox Code Playgroud)
请注意,!ip2md命令在发生TargetInvocationException的方法的IP上成功.
问题:
我在哪里可以从这里开始缩小DoSomething2中的哪一行崩溃?请注意,我无法重现崩溃,所以我只有这个(和几个重复的)转储.
附加说明:
我们有一个由WPF和/或Winforms客户端使用的库.
我们提供了一个类似于的异步方法:
Task<int> GetIntAsync()
Run Code Online (Sandbox Code Playgroud)
我们(不幸的是)还提供了一个同步包装器方法:
int GetInt();
Run Code Online (Sandbox Code Playgroud)
它本质上只是调用异步方法并调用.Result其任务.
我们最近在某些情况下意识到GetIntAsync需要在主UI线程上运行一些代码(它需要使用标记为"单个"线程模型的传统COM组件(即组件必须在主STA线程中运行而不是任何STA线程)
所以问题是,当GetInt()被称为主线程,它会死锁,因为
.Result块为主线,GetIntAsync()使用Dispatcher.Invoke尝试在主线程上运行.同步方法已被消耗,因此删除它将是一个重大变化.因此,我们选择在同步方法中使用WaitWithPumpingGetInt()来允许调用主线程.
除了使用GetInt()UI代码的客户端之外,这种方法很好.以前,他们预计使用GetInt()会使他们的UI无法响应 - 也就是说,如果他们GetInt()从按钮的click事件处理程序中调用,他们会期望在处理程序返回之前不会处理任何Windows消息.现在,消息被泵送,其UI 是响应和相同的按钮可以再次点击(他们可能没有编写自己的处理程序是重入).
如果有一个合理的解决方案,我们希望我们的客户不需要在调用期间针对响应的UI进行编码 GetInt
题:
WaitWithPumping将"调用主要"消息,但不泵送其他UI相关的消息?我正在尝试使Windows 10的Addin(使用MAF)AddInProcess.exe(由AddInProcess类创建)具有“长路径意识”。
困难源于我不拥有 AddInProcess.exe的事实。它是.NET Framework的一部分,并且存在于C:\Windows\Microsoft.NET\Framework64\v4.0.30319\AddInProcess.exe
这是我所做的事情(基于遵循Jeremy Kuhne的Blog条目.NET 4.6.2的指导以及Windows 10上的长路径):
设置AppContext开关Switch.System.IO.UseLegacyPathHandling和Switch.System.IO.BlockLongPaths到false。这使某些 .NET API开始接受长路径。但是,在后台调用本机 win32的调用仍然因System.IO.DirectoryNotFoundException其他异常而失败。
我应该做的下一件事,但不能做的是编辑应用程序的清单并在下面添加设置。但是,我没有一种(正确的)方法可以做到这一点。如果我能做到这一点,那就行了。为了证明它会起作用,我做了以下工作:
AddInProcess.exe.manifest使用以下设置创建,并将其放到旁边的目录中AddInProcess.exe。 AddInProcess.exe具有嵌入式清单(使用选中sigcheck.exe),并且嵌入式清单优先于外部清单。我通过更改导致外部清单优先的注册表设置来解决此问题(出于测试目的)。<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
Run Code Online (Sandbox Code Playgroud)
尽管上述破解工作正常,但在最终用户的计算机上执行此操作显然是不合理的,而且,这将改变所有 行为AddInProcess.exe,而不仅仅是我创建的行为。
问题:是否存在使您无法控制(AddInProcess.exe)的过程的合法方法longPathAware?
有没有办法在运行时更改此清单设置?
注意事项:
通常,对于我不希望抛出异常但代码(即编程错误)的代码,我希望我的应用程序崩溃(这样它不会破坏数据,向用户报告无效数据等).
使用时是否有获得(更接近)此行为的最佳做法Tasks?我们已经注册了一个处理程序TaskScheduler.UnobservedTaskException.问题是这可能比导致意外异常的时间晚得多.
问题: 如果有的话,我应该使用哪个选项:
我应该将我Task的操作包装在try/catch中并在catch中升级我不期望的异常吗?如果是这样,我该怎么做才能升级(即我想让它解雇AppDomain.UnhandledException事件并终止.
我应该OnlyOnFaulted在ui线程(这是Winforms应用程序)上附加continuation(),如果它不是预期的异常,它会重新抛出异常吗?
有更好或更标准的方法吗?
这是#1的样子:
var t1 = Task.Factory.StartNew(() =>
{
try
{
string path = null; // Programming error. Should have been a valid string. Will cause System.ArgumentNullException below
using (FileStream fs = File.Create(path))
{
}
}
catch (System.IO.IOException) { throw; } // Expected possible exception
catch (System.UnauthorizedAccessException) { throw; }
catch
{
// Anything caught here is not an expected exception and should …Run Code Online (Sandbox Code Playgroud)