我正在尝试用 SkiaSharp 替换 GDI+,作为数据可视化框架,该框架使用实时不断变化的工程数据呈现多层可平移可缩放图形。
在 GDI+ 中,应用程序执行了以下操作:
直到最终图像呈现的所有事情都是在一个或多个后台线程中完成的。 GUI 线程仅涉及将完成的图像绘制到 PictureBox 中。这很重要,因为还有许多其他 GUI 控件需要保持响应能力。这非常有效,只不过它是基于 CPU 的。小窗口没问题,但在 4K 屏幕上最大化会减慢渲染速度,导致程序几乎无法使用。
我想用 GPU 加速的 SkiaSharp 重新创建这个概念。
我尝试创建数十个不同的测试程序,但不断出现跨线程访问冲突,或者屏幕上没有显示任何内容,或者严重崩溃。让我问一些基本问题,而不是发布代码:
问题:
任何定义方法和注意事项的帮助将不胜感激!
一个例子:
如果您打开并运行Visual Studio(2010),然后双击PC桌面上的misc*.cs文件,该文件将在当前运行的Visual Studio实例中打开,而不是打开另一个VS实例.
如何让我自己的C#程序模仿这种行为?
换句话说,如果我有一个文件类型,如*.myfile与我的程序相关联,并且用户在Windows资源管理器中双击*.myfile,并且...... 我的程序已经运行 .....它应该打开文件而不启动Windows程序的另一个实例.如果程序未运行,则Windows可以正常启动实例.
请注意,我的程序的多个实例是允许的 - 与Visual Studio相同.
任何建议,将不胜感激 !!
背景:
我有兴趣使用MEF在使用C#和.NET 4.0的WinForm应用程序中提供插件架构,但我不清楚一些事情.
第一:我还没有在C#中构建DLL的工作,我对DLL Assemblies的概念以及DLL如何正常加载到内存中有点模糊(意思是,根据需要一次性或分段)
意图:
该程序将是一个机器硬件控制框架,将由一个主要的WinForm GUI组成,这是一个具有基本工具栏,菜单等的通用环境 - 但没有批量GUI内容.(想想:MDI家长,但实际上并非如此).
插件提供特定机器的所有控件.许多可能的插件中的每一个都包含30到50个大型UserControl,每个用户控件都包含许多WinForm控件和大量支持代码,构成了各种机器控制面板.
这意味着主程序是一个轻量级的通用框架,插件包含将在主程序用户界面中显示的大量GUI控件和功能,包括许多图标,图像和其他资源.这将使插件DLL可能非常大.
目标是允许用户从菜单中选择一个插件,然后在选择时加载并运行插件,然后插件将大部分空的主GUI填充面板,菜单和工具箱.
为此,我需要首先从每个插件中提取元数据以填充程序的初始菜单,其中包括插件标题,描述,图标,版本号和其他信息位.
以下是问题:
使用MEF,如果我尝试从存储在插件文件夹中的每个大型DLL中读取元数据,是否会在访问元数据值之前将整个DLL复制到内存中?
如果是这样,有没有办法打开每个DLL文件,只读取元数据到内存中构建初始菜单 - 然后通过MEF加载完整选定的DLL?
我假设通过MEF读取插件的典型DirectoryCatalog和AggregateCatalog模板将所有发现的DLL复制到内存中并将它们存储在目录集合中.
DLL是否包含一个连续的代码块(程序集),或者它们是否包含多个单独的块,这些块根据需要单独索引并复制到内存(多个程序集)?
我可能不了解基本面,也许是令人困惑的条款.我将非常感谢对MEF,DLL和程序集的加载行为的任何了解.谢谢 !
C#.NET 4.0 WinForms
我开始实现本教程中的 MEF示例代码,该代码描述了为元数据创建自定义ExportAttribute属性.在我尝试在元数据中包含资源文件中的图像之前,一切都在顺利进行.目标是将每个插件DLL的标题,描述和图标提取为元数据,以便在主程序中构建插件菜单.
我现在得到编译错误:
"属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式"
所以现在我有一个问题,需要弄清楚:
1)如何在属性中包含图像?
要么
2)如何在不使用属性的情况下在MEF中包含元数据?
这是我正在使用的代码:
在合同类中:
// Metadata contract interface
public interface IPlugInMetadata
{
string PlugInTitle { get; }
string PlugInDescription { get; }
Image PlugInIcon { get; }
}
// Plug-In contract interface
public interface IPlugIn
{
void StartPlugIn(object systemObject);
void StopPlugin();
}
Run Code Online (Sandbox Code Playgroud)
插件DLL中的自定义属性:
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PluginMetadataAttribute : ExportAttribute
{
public string title { get; set; }
public string description { get; set; } …
Run Code Online (Sandbox Code Playgroud) 我正在尝试为.Net学习新的Reactive Extensions框架,这听起来像是我的应用程序的完美解决方案.在研究了示例(并且仍然相当弱的LINQ)之后,我正在努力弄清楚如何利用RX框架来完成下面的任务.
目标是在自定义数据源和GUI之间创建可配置事件"中继".继电器将使用LINQ测试和过滤传入事件,在等待下一个时间间隔时将限定事件缓存在列表中,然后同步到GUI线程并按照接收顺序回放事件.
如何使用RX来协调缓存,过滤和中继多个事件,例如用于添加,更改和从自定义数据源中删除值的事件?
这可能要求很多,但是如何解决这个问题的任何指导都将非常感激.见下面的示例代码......
public delegate void EventDelegateAdd(Thing thing);
public delegate void EventDelegateChange(Thing thing);
public delegate void EventDelegateRemove(Thing thing);
public delegate void EventDelegateBulkChangesStart();
public delegate void EventDelegateBulkChangesEnd();
// The "Things" that are stored in MyCustomDataSource
public class Thing
{
public string Key { get; set; }
public string Title { get; set; }
public object OtherStuff { get; set; }
}
// A custom observable data source with events that indicate when Things are
// added, changed, or removed. …
Run Code Online (Sandbox Code Playgroud) 下面的例子显示了意图。该示例迭代对象数组,并创建一个具有加载默认值的相同类型的数组。值本身不需要从一个列表复制到下一个列表。这是列表的“类型克隆”。
下面的代码会为激活器产生以下错误:
“System.Int32 不是 GenericTypeDefinition。MakeGenericType 只能在 Type.IsGenericTypeDefinition 为 true 的类型上调用。”
Activator、CreateInstance 和 MakeGenericType 的细节对我来说仍然有点混乱。
如何更改代码以避免错误?
任何建议,将不胜感激。
private void Test()
{
object[] a = new object[] {100, "Text", new clsMyClass()};
object[] b = new object[a.Length];
for (int i = 0; i < a.Length; i++)
{
b[i] = Activator.CreateInstance(a[i].GetType().MakeGenericType());
}
for (int i = 0; i < b.Length; i++)
{
Console.WriteLine(b[i].GetType().ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
预期输出为:
结果值将是: