我一直在阅读C#中的新操作符async和await操作符,并试图找出它们可能对我有用的环境.我研究了几篇MSDN文章,这里是我在线之间阅读的内容:
您可以使用asyncWindows窗体和WPF事件处理程序,因此在执行大量操作时,它们可以执行冗长的任务而不会阻止UI线程.
async void button1_Click(object sender, EventArgs e)
{
// even though this call takes a while, the UI thread will not block
// while it is executing, therefore allowing further event handlers to
// be invoked.
await SomeLengthyOperationAsync();
}
Run Code Online (Sandbox Code Playgroud)
使用await必须的方法async,这意味着async在代码中某处使用任何函数最终会强制调用序列中的所有方法从UI事件处理程序到最低级别的async方法async.
换句话说,如果您创建一个带有普通旧旧ThreadStart入口点的线程(或者具有良好旧版本的Console应用程序static int Main(string[] args)),那么您将无法使用async,await因为您必须await使用它async,并使用它的方法,并且因此在调用方法中你还必须使用await并制作那个async,依此类推.但是一旦你到达线程入口点(或Main()),就没有await …
我有以下项目结构:
Library1 <--[project reference]-- Library2 <--[ref]-- Executable
-------- -------- ----------
ContentFile .cs files .cs files
.cs files
Run Code Online (Sandbox Code Playgroud)
所有项目引用都具有CopyLocal = true.
当我构建项目时,ContentFile会将其复制到Library2输出目录,而不是复制到Executable输出目录,这意味着ContentFile应用程序运行时缺少可执行文件.
为什么内容文件被复制到Library2输出目录,但不是Executable?有没有办法将它复制到后者(我想在没有构建事件的情况下这样做,因为我相信人们会忘记这一点)?
我正在寻找一个合理且可维护的解决方案; 在添加新项目或新的间接引用的内容文件时,只需要很少的工作,因此尽可能不要忘记这样做.
使用Post-Build事件(如xcopy ../Library/bin/Debug/SomeDll.dll bin/Debug); 并手动设置项目的输出目录$(SolutionDir)/bin/...而不是默认(每个项目),两者都很快变得一团糟.将内容文件添加为"主项目"中的链接也太乏味了.如果C#具有与Visual C++相同的输出文件的默认设置(即$SolutionDir/$Platform/$Configuration),那就没问题了,但事实并非如此.
我也考虑过根本不使用标准的MSBuild程序并编写自定义构建目标(比如在Atmel Studio中使用gcc),但我没有做得太远.此外,我希望Visual Studio的标准"构建"和"调试"命令像往常一样工作.
以下是我正在做的更多细节.
我有一个Executable项目的解决方案.此外,还有很多项目可以调用Plugin.通过托管项目引用Executable引用所有这些Plugin.
由于插件项目是针对可执行文件定制的,但可能具有可重用的组件,因此主要功能通常在External项目中实现,使Plugin项目仅仅是包装器(并非总是如此).
所述External项目有时使用由第三方提供的本机DLL.然后将这些DLL External作为内容文件添加到项目中并Copy to output dir设置为 …
今天在大学里我被一位教授推荐,我会(this != ©)在复制构造函数中检查,类似于你在重载时应该怎么做operator=.但是我质疑这是因为this在构造对象时我无法想到任何与参数相等的情况.
他承认我提出了一个很好的观点.所以,我的问题是,执行此检查是否有意义,还是不可能搞砸了?
编辑:我想我是对的,但我会暂时保持开放状态.也许有人想出一些疯狂的神秘c ++魔法.
Edit2:Test a(a)编译MinGW,但不编译MSVS10.Test a = a编译两者,所以我认为gcc会表现得有些相似.不幸的是,VS 没有显示"使用未经初始化的变量"的调试消息.但它确实正确地显示了此消息int i = i.这真的可以被认为是c ++语言的缺陷吗?
class Test
{
Test(const Test ©)
{
if (this != ©) // <-- this line: yay or nay?
{
}
}
Test &operator=(const Test &rhd)
{
if (this != &rhd) // <-- in this case, it makes sense
{
}
}
};
Run Code Online (Sandbox Code Playgroud) 我注意到WPF应用程序中这种非常奇怪的行为.
我有一个MainWindow,使用Show()来自显示App.OnStartup.说MainWindow可以打开(非模态)SubWindow,也可以使用Show().SubWindow的Owner设置为MainWindow.
何时SubWindow关闭,MainWindow再次可见(好).
某些操作可能会导致SubWindow打开第三个窗口作为模式对话框,使用ShowDialog()(Owner设置为SubWindow).当该模态对话框在a的生命周期中至少打开并关闭一次时SubWindow,就会发生奇怪的事情.
关闭后SubWindow,MainWindow不会进入视野.相反,无论随机窗口后面 MainWindow映入眼帘.任何人都可以向我解释为什么会发生这种情况,以及如何解决它?
模态对话框是使用正常Window显示还是使用显示ShowDialog()的消息框没有区别MessageBox.Show().
这是一些重现这个的最小代码.在visual studio中创建一个新的WPF应用程序,并将其粘贴到预先生成的MainWindow.xaml.cs中
然后,按键盘上的一个键只打开一个窗口,关闭它,按预期行为.按两个键,关闭两个键,然后第一个窗口在Visual Studio后面(推测).
public MainWindow()
{
InitializeComponent();
this.PreviewKeyDown += (sender, e) =>
{
if (this.Owner is MainWindow)
{
// we're the SubWindow
MessageBox.Show("I am a modal …Run Code Online (Sandbox Code Playgroud) 今天上班时,我偶然发现了一个让我疯狂的问题.
基本上我的目标是:
我有一个UserControl1,具有类型的字段Collection<Class1>和相应的属性Collection<Class1> Prop.像这样:
public class UserControl1 : UserControl
{
private Collection<Class1> field = null;
// later changed to:
//private Collection<Class1> field = new Collection<Class1>();
[Category("Data")]
[DefaultValue(null)]
[Description("asdf")]
public Collection<Class1> prop
{
get { return field; }
set { field = value; }
}
}Run Code Online (Sandbox Code Playgroud)
// later added:
//[Serializable]
public class Class1
{
private bool booltest; public bool Booltest { get...set...}
private int inttest; public int Inttest { get...set...}
}Run Code Online (Sandbox Code Playgroud)
如果你已经知道我搞砸了什么:不需要阅读其余部分.我将描述我究竟做了什么.
现在我把它 …
遗憾的是,我并不完全回答我想知道的事情:
上述问题的答案表明它与在开始菜单中添加快捷方式有关,但这不是唯一的原因.到目前为止,我一直无法可靠地弄清楚是什么让Windows认为我的应用程序首先是安装程序,为什么Windows认为它失败了?
我不想简单地在清单中使用兼容性标记来抑制消息.我想写一个合适的解决方案,并告诉Windows我的安装是否失败.此外,使用推荐设置选项的安装是什么,与对话框一起出现?我该如何正确使用此功能?同样,我不想简单地忽略Windows提供的功能,我想使用它们.
我一直在浏览MSDN但没有成功.我问谷歌,但我能找到的方法是使用清单或注册表中的兼容性技巧来抑制消息.如果有人能够在MSDN上提供可以很好地涵盖这一主题的可行资源,我将非常感激.
到目前为止,我正在使用一个使用多个Windows API调用的自定义安装程序.除了注册两个服务之外,我没有搞乱Windows注册表.它也具有requireAdministrator所请求的执行级别(不是任何人都关心,但这是令人惊讶的干净和简单 - 它只是项目设置中的标志).我目前没有使用MFC或CLR.
我一直想知道是否有任何命名对象,如何使用ALLCAPS作为类型以及何时追加_t(以及何时不使用任何东西?).我知道K&R早些时候发布了有关如何使用C的各种文件,但我找不到任何关于此的内容.
在C标准库类型中,_t似乎是prettys占主导地位
time_t
clock_t
uint32_t
size_t
sig_atomic_t
...
Run Code Online (Sandbox Code Playgroud)
,而不是FILE,va_list或struct tm.实际上有规则还是完全随意的?Microsoft总是在他们的Windows API中使用ALLCAPS中的类型名称,至少看起来比C库更加一致,坦率地......
我有以下OpenCL内核:
kernel void ndft(
global float *re, global float *im, int num_values,
global float *spectrum_re, global float *spectrum_im,
global float *spectrum_abs,
global float *sin_array, global float *cos_array,
float sqrt_num_values_reciprocal)
{
// MATH MAGIC - DISREGARD FROM HERE -----------
float x;
float y;
float sum_re = 0;
float sum_im = 0;
size_t thread_id = get_global_id(0);
//size_t local_id = get_local_id(0);
// num_values = 24 (live environment), 48 (test)
for (int i = 0; i < num_values; i++)
{
x = cos_array[thread_id * …Run Code Online (Sandbox Code Playgroud) 我有一个应用程序需要以非常精确的间隔执行代码.为此,我还需要Windows的调度程序分辨率增加到1ms timeBeginPeriod.
为此,我有一个原生的C++ DLL,通过TimerQueueTimer以1ms的间隔(所有本机代码)引发的回调处理所有时间关键的事情.
应用程序本身是一个.NET应用程序(C#,所以纯CLR).本机dll使用缓冲,因此C#代码本身不需要时间关键,只要它每50 ms左右获得一些执行时间.
当垃圾收集器出现时,是否还会暂停或延迟程序中任何计时器回调的执行?(换句话说:.NET程序的非确定性是否会扩展到它使用的本机代码片段?)我没有找到这个精确问题的答案.MSDN文档的链接最让人放心.
我正在使用.NET 4.0
摘要
似乎在Windows窗口模式下,与OpenGL的vsync中断了。我尝试了不同的API(SDL,glfw,SFML),但都得到了相同的结果:虽然帧频受到限制(根据我尝试过的多个60 Hz设置的CPU测量,始终保持16-17 ms左右),并且实际上,CPU大多数时候都处于睡眠状态,经常跳过帧。视机器和CPU使用率(而非渲染)而定,这可能与将帧速率有效降低一半一样糟糕。此问题似乎与驱动程序无关。
如何在窗口模式下使用OpenGL在Windows上的Windows上具有有效的vsync或具有这些属性的类似效果(如果我忘记了一些值得注意的内容,或者如果某些内容不明智,请发表评论):
细节/一些研究
当我用谷歌搜索opengl vsync stutter或opengl vsync frame drop类似的查询时,我发现很多人都遇到了这个问题(或一个非常类似的问题),但是似乎并没有解决实际问题的连贯解决方案(在gamedev stackexchange上也有很多未充分回答的问题;也许多省力的论坛帖子)。
总结一下我的研究:似乎新版本Windows中使用的合成窗口管理器(DWM)会强制执行三倍缓冲,并且会干扰vsync。人们建议禁用DWM,不使用vsync或全屏显示,所有这些都不是解决原始问题的方法(FOOTNOTE1)。我还没有找到详细的解释,为什么三重缓冲会导致vsync出现此问题,或者为什么在技术上无法解决该问题。
但是:我还测试了即使在非常弱的PC上,在Linux上也不会发生这种情况。因此,在技术上(至少通常),对于基于OpenGL的硬件加速,必须启用功能vsync而不跳过帧。
另外,在Windows(启用vsync)上使用D3D而不是OpenGL时,这也不是问题。因此,从技术上讲,必须能够在Windows上运行vsync(我尝试了新的,旧的和非常旧的驱动程序以及不同的(旧的和新的)硬件,尽管我可用的所有硬件设置都是Intel + NVidia,所以我不这样做。不知道AMD / ATI会发生什么。
最后,肯定有用于Windows的软件,包括游戏,多媒体应用程序,创意作品,3D建模/渲染程序等,它们使用OpenGL并在窗口模式下正常工作,同时仍可以准确地渲染,而无需在CPU上等待,并且没有掉帧。
我注意到,当使用传统的渲染循环
while (true)
{
poll_all_events_in_event_queue();
process_things();
render();
}
Run Code Online (Sandbox Code Playgroud)
CPU在该循环中必须完成的工作量会影响停顿的行为。但是,这绝对不是CPU过载的问题,因为该问题也发生在一个人可以编写的最简单的程序之一(请参见下文)中,并且在一个功能强大的系统中,它什么也不做(该程序什么也不做)除了清除每帧上具有不同颜色的窗口,然后显示它)。
我还注意到,它似乎永远不会比跳过其他所有帧更糟(即,在我的测试中,在60 Hz的系统上可见帧率始终在30到60之间)。在运行程序时,您可能会观察到某种违反奈奎斯特采样定理的情况,该程序在奇数和偶数帧上将背景颜色更改为2种颜色,这使我相信某些内容未正确同步(即Windows或其OpenGL实现中的软件错误)。同样,就CPU而言,帧速率是坚如磐石的。另外,timeBeginPeriod在我的测试中没有明显的影响。
(FOOTNOTE1)但应注意,由于DWM,在窗口模式下不会发生撕裂(这是使用vsync的两个主要原因之一,另一个原因是使CPU处于最大可能的睡眠时间)而不丢失任何框架)。因此,对于我来说,有一个在应用程序层中实现vsync的解决方案是可以接受的。
但是,我认为唯一可行的方法是,有一种方法可以明确(准确)地等待页面翻转发生(可能会发生超时或取消),或者查询在以下情况下设置的非粘性标志:页面被翻转(以不强制刷新整个异步渲染管道的方式,例如glGetError,这种方式),并且我也没有找到一种方法来执行。
这是一些代码,可以运行一个快速的示例来演示此问题(使用SFML,我发现上班时最痛苦)。
您应该看到均匀的闪烁。如果您看到同一颜色(黑色或紫色)超过一帧,那就不好了。
(这会以屏幕的刷新率闪烁屏幕,因此可能出现癫痫警告):
// g++ TEST_TEST_TEST.cpp -lsfml-system -lsfml-window -lsfml-graphics -lGL
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include <iostream>
int main()
{
// create …Run Code Online (Sandbox Code Playgroud) .net ×4
c# ×4
c++ ×2
windows ×2
async-await ×1
c ×1
class ×1
designer ×1
dialog ×1
installation ×1
installer ×1
interop ×1
modal-dialog ×1
opencl ×1
opengl ×1
properties ×1
rendering ×1
scheduling ×1
types ×1
winapi ×1
window ×1
wpf ×1