[英]How to handle dll function calls inside a thread in c#
我正在后台线程内调用DLL函数之一。
问题是当DLL丢失时,我的应用程序直接崩溃。 我也尝试过try-catch,但是应用程序还是崩溃了?
当我在主UI线程上调用DLL函数时,我的应用程序将处理该异常。
如何在后台线程中处理异常?
mythread = new Thread(CM);
mythread.IsBackground = true;
mythread.Start();
private void CM()
{
// Perform a protection check with default options
try
{
ret_code = myclass.CheckProtection(myclass.CheckProtectionOptions.Default);
}
catch(Exception cm)
{
throw cm;
}
}
在这里快速回答。
某些DLL与启动它的第一个线程具有相似性。 我过去所做的就是通过循环使该线程在后台保持活动状态。 然后,您在该DLL加载线程中侦听事件。 您可能需要重新构造代码以侦听事件,而不是调用DLL调用。
希望有帮助吗?
我添加了一些示例代码,您可以尝试一下,然后看看会发生什么。 它不是完美的,但是它应该有助于说明如何保持线程活动。 还有其他方法可以做到这一点,但我只是想保持示例简单
using System;
using System.Reflection;
using System.Threading;
namespace ConsoleApplication3
{
internal class Program
{
private static void Main(string[] args)
{
var newThread = new Thread(DllLoader.DoWork);
newThread.Start();
//My other application Logic
}
public class DllLoader
{
public enum ThingsICanDo
{
Jump,
Duck,
Run,
Quit
}
private static bool appStillRunning;
private static object myInstanceDllType;
private static void CheckForStuffToDo()
{
//Much better to use events, and pass the message inthe event
// then do what the message wants, and but I am keeping this breif
// for this example.
var DoNext = (ThingsICanDo) Enum.Parse(typeof (ThingsICanDo), Console.ReadLine(), true);
switch (DoNext)
{
case ThingsICanDo.Jump:
//Do jump stuff
Console.WriteLine("Jump");
//myInstanceDllType.JumpStuff();
break;
case ThingsICanDo.Duck:
Console.WriteLine("Duck");
//myInstanceDllType.DuckStuff();
//Do duck stuff
break;
case ThingsICanDo.Run:
Console.WriteLine("Run");
//myInstanceDllType.RunStuff();
//Do run stuff
break;
case ThingsICanDo.Quit:
//Do exit stuff
Console.WriteLine("Bye");
Thread.CurrentThread.Abort();
break;
}
}
public static void DoWork()
{
var externalAssembly = Assembly.LoadFrom("/path/my.Dll");
myInstanceDllType = Activator.CreateInstance("DLLTypeINeed");
while (appStillRunning)
{
try
{
CheckForStuffToDo();
}
catch (Exception e)
{
//Log e
Console.WriteLine(e);
}
Thread.Sleep(1000);
//Much better to use semaphore.wait or something similar, but this is a simple example
}
}
}
}
}
属于“您不应该做的事”类别。 这是一个部署错误,您总是需要大声的消息来告诉别人进行修复。 但是,问题在于,try / catch放置不正确。 即时编译器会抛出该异常,它会在尝试开始运行之前试图生成机器代码,因此会产生异常。 用线程执行此操作会使它更加复杂,只有CLR才能捕获它。
您将需要帮助,您必须有意识地编写一些可以持续工作的存根方法。 然后,它又必须调用危险代码。 现在,您可以注入必要的try / catch。 您还必须确保这在Release版本中有效,这要求您减慢抖动并防止它嵌入危险的方法。 这需要一个属性。 像这样:
using System.Runtime.CompilerServices;
...
mythread = new Thread(CMStub);
mythread.IsBackground = true;
mythread.Start();
...
void CMStub() {
try {
CM();
}
catch (Exception ex) {
LogFatalError(ex); // Don't throw!
}
}
[MethodImpl(MethodImplOptions.Noinlining)]
void CM() {
// risky code here
}
最初使用的代码throw无效。 永远不要忽略留下面包屑的需要,这样您就可以知道线程没有执行应做的事情。 某种记录器或EventLog类是绝对最低要求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.