从性能角度来看,使用静态方法是否比 lambda 表达式更好?由于lambda表达式每次都会生成一个闭包对象并保存对所使用的局部变量的引用。
D .Stark's questions
以简化形式,我的代码如下所示:
async Task Foo() {
while(true) {
...
lock (syncObj) {
...
File.AppendAllText(FileName, data);
}
}
}
void Main() {
...
tasks.Add(Task.Factory.StartNew(Foo, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default).Unwrap());
...
}
我很少得到IOException
:该进程无法访问文件“路径”,因为它正在被另一个进程使用。如果对文件的访问是通过锁结构同步的,这怎么可能呢?代码中的其他任何地方都不会访问该文件,并且没有其他进程正在使用该文件。也许这是WinAPI调用背后的某种特性AppendAllText
,很少能在文件释放之前执行完成?
.NET 6.0、Windows
当从不同线程执行多个请求时,HttpClient 是否会同时创建到一个站点(或多个站点)的多个连接并并行执行所有请求,彼此独立?出于优化目的,在执行请求后,HttpClient 会使连接保持打开状态一段时间,以防向同一站点发出更多请求。这与并行查询相关吗?也就是说,如果我们同时向站点 A 和站点 B 发出请求,并且在一段时间后重复请求,则不会重新创建连接。如果事情不顺利,解决方案可能是为每个域(或一个)创建一些客户端池。
我正在实现一种算法,用于使用 TCP 打孔技术在两个客户端之间创建直接连接,该连接可能位于 NAT 后面。我在C++中使用WinSock2接口。
通过服务器交换外部地址后,客户端关闭连接(shutdown
使用SD_BOTH
和标志调用closesocket
)并尝试直接创建新连接(套接字绑定到以前使用的端口)。接下来,发生数据交换。
如果成功,TCP 数据包日志如下所示:
我在家庭网络上进行测试,两个客户端都在同一台计算机上运行。我认为,为了正确实施,应该没有区别。
192.168.153.196:52023 - 客户端 1、192.168.153.196 : 51722 - 客户端 2。在屏幕截图中,您可以看到客户端 1 发送的 SYN 段已成功传递到客户端 2,随后是 ACK 段,并开始通过路由器进行数据交换。在这种情况下,我们有一种 NAT,其中内部端口 = 外部端口(即,例如客户端 1 也从端口 52023 访问公共网络)。
当客户端无法相互建立连接时,请考虑以下日志:
192.168.1.106:52478 - 客户端 1、192.168.1.106 : 52477 - 客户端 2。接下来,日志中会重复发送一系列 SYN 段,直到客户端确信无法建立连接。显然,本例中未创建 NAT 映射。这里有一种不同类型的 NAT - 内部端口与外部端口不对应;客户端也运行在同一台机器上。
这是另一个不成功的示例,但已经在第一个示例的网络上(192.168.153.196:51640 - 客户端 1、192.168.153.196: 51639 - 客户端 2):
在这种情况下,据我了解,由于某种原因路由器重置了连接。
问题是,我做错了什么?每个客户端都知道另一个客户端的正确外部地址,在关闭与服务器的连接后短暂超时后,在大约相同的时间点,它们尝试从旧端口(调用)相互创建连接,但是路由器重置连接或不创建 NAT 条目connect
。
还有另一个奇怪的时刻。建立连接后,从交换开始最多几分钟,会出现以下情况:
随后几次尝试重新发送均不成功 - 数据包似乎被路由器忽略并且未转发。在这种情况下,调用send
不会显示错误,而recv
只是在接收方被阻止,因为它看不到数据。
我正在使用桌面复制 API 从屏幕捕获图像。除了绘制光标之外,一切正常 -IDXGISurface1::GetDC
它返回错误代码 0x887A0001 DXGI_ERROR_INVALID_CALL
(无效参数数据)。此外,前 1-2 张捕获的图像有时会变成空的(填充为黑色)。告诉我如何解决它?
CComPtr<ID3D11Device> pDevice;
CComPtr<IDXGIOutputDuplication> pOutputDuplication;
BOOL Init()
{
CComPtr<IDXGIFactory1> pDxgiFactory;
CComPtr<IDXGIAdapter1> pDxgiAdapter;
CComPtr<IDXGIOutput> pDxgiOutput;
CComPtr<IDXGIOutput1> pDxgiOutput1;
hDC = GetDC(NULL);
CHECK_HR(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&pDxgiFactory)));
CHECK_HR(pDxgiFactory->EnumAdapters1(0, &pDxgiAdapter));
CHECK_HR(pDxgiAdapter->EnumOutputs(0, &pDxgiOutput));
CHECK_HR(pDxgiOutput->QueryInterface(__uuidof(IDXGIOutput1), reinterpret_cast<void**>(&pDxgiOutput1)));
// Supported feature levels.
const D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_1
};
D3D_FEATURE_LEVEL d3dFeatLvl;
ID3D11DeviceContext* pImmediateContext = NULL;
CHECK_HR(D3D11CreateDevice(pDxgiAdapter, D3D_DRIVER_TYPE_UNKNOWN,
0, 0, featureLevels, ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION, &pDevice,
&d3dFeatLvl, &pImmediateContext));
// Create desktop duplication.
CHECK_HR(pDxgiOutput1->DuplicateOutput(pDevice, &pOutputDuplication));
return TRUE;
}
HBITMAP CaptureScreenshot()
{
DXGI_OUTDUPL_FRAME_INFO DxgiFrameInfo;
IDXGIResource* pDesktopResource;
ID3D11Texture2D* pAcquiredDesktopImage;
AcquireFrame:
if (FAILED(pOutputDuplication->AcquireNextFrame(5000, &DxgiFrameInfo, &pDesktopResource)))
{
return NULL;
}
if (FAILED(pDesktopResource->QueryInterface(__uuidof(ID3D11Texture2D),
reinterpret_cast<void**>(&pAcquiredDesktopImage))))
{
pDesktopResource->Release();
return NULL;
}
pDesktopResource->Release();
if (DxgiFrameInfo.LastPresentTime.QuadPart == 0)
{
std::this_thread::sleep_for(std::chrono::milliseconds(20));
pAcquiredDesktopImage->Release();
pOutputDuplication->ReleaseFrame();
goto AcquireFrame;
}
HBITMAP hBitmap = ExtractBitmap(hDC, pAcquiredDesktopImage, pDevice);
pAcquiredDesktopImage->Release();
pOutputDuplication->ReleaseFrame();
return hBitmap;
}
有一些大型类是用 C++ 实现的。我需要在 C# 项目中使用它。为了节省时间并且不重写代码,我选择了用 C++/CLI 编写此类的包装器,并将其全部放入类库中。但是,我在使用 1 种方法时遇到了困难,该方法将回调函数的指针作为参数。
情况如下:本机类有一个方法,该方法接受一个指向某个函数的指针,该函数在某些事件发生时被调用。任务是在包装类中提供类似的方法,但将分别传递委托而不是指针。
我简化了代码来演示该问题:
class CFoo
{
public:
bool FooMember;
CFoo()
{
FooMember = true;
}
void Call(void(*callback)(CFoo))
{
CFoo foo = CFoo();
std::thread thr([=]() { callback(foo); });
thr.join();
}
};
ref class FooWrapper
{
public:
delegate void ManagedCallback(FooWrapper^ foo);
private:
delegate void UnmanagedCallback(CFoo foo);
ManagedCallback^ Callback;
void FooProc(CFoo foo)
{
std::cout << "FooProc: " << (foo.FooMember ? "true" : "false") << std::endl;
Callback(gcnew FooWrapper(&foo));
}
public:
CFoo* foo;
FooWrapper()
{
foo = new CFoo();
}
FooWrapper(CFoo* foo)
{
this->foo = foo;
}
void Call(ManagedCallback^ callback)
{
Callback = callback;
UnmanagedCallback^ unmanagedCallback = gcnew UnmanagedCallback(this, &FooWrapper::FooProc);
IntPtr^ methodPtr = Marshal::GetFunctionPointerForDelegate(unmanagedCallback);
foo->Call(static_cast<void(*)(CFoo)>(methodPtr->ToPointer()));
}
};
ref class Program
{
public:
FooWrapper^ Foo;
void Callback(FooWrapper^ foo)
{
Foo = foo;
std::cout << "Callback: " << (foo->foo->FooMember ? "true" : "false") << std::endl;
}
void Start()
{
FooWrapper^ w = gcnew FooWrapper();
w->Call(gcnew FooWrapper::ManagedCallback(this, &Program::Callback));
}
};
int main(array<System::String ^> ^args)
{
Program^ c = gcnew Program();
c->Start();
CFoo foo = *c->Foo->foo; // <- AccessViolationException
return 0;
}
控制台输出:
FooProc:正确
回调:true
一旦CFoo::Call
方法中创建的线程完成执行,类成员FooWrapper::foo
就会被销毁。我尝试查看对析构函数的调用FooWrapper
并CFoo
确保该对象没有被破坏。您还可以在尝试取消引用之前查看指针本身的数值,并确保指针有效。
例外:
System.AccessViolationException:“尝试读取或写入受保护的内存。这通常表明其他内存已损坏。
也许有一种更好的方法来实现包装器,或者您可以以某种方式修复现有的方法。
WINAPI函数如何MoveFile
移动文件或文件夹:它是简单地更改文件在FAT中的位置信息,还是复制数据并从磁盘上删除原始文件(换句话说,称为CopyFile
)DeleteFile
?如何追踪操作进度?有一个 WINAPI 函数MoveFileTransacted,但是,文档强烈建议不要使用它,但我没有找到专门用于此任务的任何替代方法。
static async Task Foo() {
while (true) {
await Task.Delay(1000);
Console.WriteLine("PRINT");
}
}
static void Main(string[] args) {
var strip = new MenuStrip();
Foo();
Console.ReadKey();
}
此代码示例演示了奇怪的行为:实例化后MenuStrip
,该方法Foo
在调用时被阻塞Task.Delay
。如果您不创建实例MenuStrip
,那么一切都会正常运行 - 每隔一秒就会向控制台打印一条消息PRINT
。为什么会这样?
目标框架:.NET 6.0
目标操作系统:Windows
服务器排序选项:SQL_Latin1_General_CP1_CI_AS
. DB 排序参数已从 更改SQL_Latin1_General_CP1_CI_AS
为Cyrillic_General_CI_AS
,但我仍然看到字段中的值而不是 Cyrillic ????????????
。尝试在之前使用INSERT
前缀,但结果是一样的。如何在数据库字段中正确保存西里尔字符?我使用的数据类型是 VARCHAR(N)。另一台服务器上有另一个数据库,服务器的排序参数最初设置为那里,具有完全相同数据类型的字段安全地存储西里尔字母,所以在我看来问题不在于数据类型。N
''
Cyrillic_General_CI_AS
任务是将文本插入输入。但是,我无法做到这一点。尝试了以下方法:
#1(触发任何事件时重置文本,例如鼠标单击表单)
inputField.value = 'TEXT';
#2(类似于 #1)
inputField.value = 'TEXT'
inputField.dispatchEvent(new Event('input', { bubbles: true }));
#3(焦点发生但文本插入没有)
inputField.dispatchEvent(new Event('focus', { bubbles: true, cancelable: true }));
const pasteEvent = Object.assign(new Event('paste', { bubbles: true, cancelable: true }), {
clipboardData: {
getData: (type = pasteType) => 'PASTED TEXT',
},
});
inputField.dispatchEvent(pasteEvent);
输入:
<input data-marker="code-input" name="code" maxlength="20" autocomplete="off" placeholder="Ввод" type="text" class="input-input-Zpzc1" value="">
我提供表单的 HTML 代码:https ://pastebin.com/ZEEE36x4
我在页面上执行的以下脚本(该站点不属于我)旨在在表单的输入字段中输入某些数据:
var inp = document.querySelector('[data-marker="registration-form/input"]');
inp.select();
inp.focus();
inp.value = '79000000000';
问题是按下按钮继续(表单上标记为“继续”的按钮)重置设置值input.value
。调用select()
, focus()
,click()
什么都不做,尽管它们应该激活输入字段。如果您手动执行此操作,则一切正常。我不明白如何激活该字段中的输入。有任何想法吗?
这种设计的线程安全性如何:
ConcurrentDictionary<Type1, Dictionary<Type2, Type3>> threadSafeDictionary = new ...
可能存在多个线程修改和读取嵌套的Dictionary
.
在 Chrome 扩展程序中,我尝试使用 XMLHttpRequest 加载一些脚本,但出现以下错误:
从源“...”访问“...”处的 XMLHttpRequest 已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头。
如何绕过 CORS 策略并仍然加载所需的脚本?
要移除标准窗框,请将属性设置Window.WindowStyle
为None
。我们得到这个窗口:
我们看到一个 1 像素的灰色边框,顶部有一个白色(我猜是窗口背景颜色)条纹和一个投影。窗口是可调整大小的,并且调整大小的框架位于可见窗口框架之外(顶部边框除外,Microsoft 决定它应该正好在可见框架内 - 而不是在阴影上)。
我想让这个顶部边框不可见,在顶部留下调整窗口大小的选项。我很高兴有一个解决方案,它可以让我自己的按钮简单地放在这个框架顶部的边缘。
您可以制作一个窗口AllowsTransparency
,但随后阴影、窗口大小调整框架将消失(显然,整个非客户区都消失了,窗口完全由我们支配)并最小化/最大化动画。当然,您可以尝试自己完成所有操作:只需使用一些元素(例如 )创建自己的窗口大小调整框架Rectangle
,在其下绘制阴影,忘记最小化/最大化动画。
但是有一个非常令人不快的效果 - 当窗口调整大小超出这种非标准框架时,它会抽搐很多。那些。一个正常的窗口调用SetWindowPos
会AllowsTransparency
导致这样的问题。使用标志SWP_NOCOPYBITS
并不能解决问题(这意味着您不需要提供创建处理程序 on WM_WINDOWPOSCHANGING
(和 on WM_NCCALCSIZE
,据我所知,类似地)以及在那里做什么)。通常这种行为是由于给应用程序更新窗口内容的临时配额过期了,Windows 本身复制了左上角的内容,并用背景颜色填充了剩余的窗口空间(然后应用程序本身必须“赶上”)。在禁用 Aero 的 Windows 7 上,问题仍然存在。
所以问题是如何将自定义元素放置在标准窗口大小调整边框之上,或者消除调用SetWindowPos
这种窗口样式的效果。
为什么WindowChrome
它不起作用:是的,使用这种WindowChrome
抽搐确实消失了,但条件是它GlassFrameThickness
不是 0 和NonClientFrameEdges
not None
。后者在指示的一侧添加相同的条带。AllowsTransparency
不能与此类属性值一起使用(我只是没有从任务栏最大化窗口)。
该项目正在.NET 4.5 下构建。
要获得我使用的序列号和轮胎类型IOCTL_STORAGE_QUERY_PROPERTY
。但是,STORAGE_DEVICE_DESCRIPTOR
它不包含正确的信息。至于序列号,据我了解,事情是这样的:原则上它可能不在某些磁盘上,同一组字节可以有不同的解释(如果有的话,有没有通用的方法?)。该字段BusType
还显示了 RAID 总线的类型,尽管事实上我有 NVM Express。如何获取正确的信息?该解决方案应该可以在 Windows XP 下运行。
如果在库函数中分配了一块堆内存,则将指针传递给加载该库的应用程序可能会适得其反。它与什么有关?
当然,我理解加载的DLL会有自己的内存管理器,会被加载到共享内存区。这意味着在其中声明的变量将存储在某种堆栈中,而动态分配的内存位于其“堆”中。malloc
在内部,它似乎存储了它已分配的内存量以及分配的位置,因此,在调用时free
,如果内存管理器相同,它也知道此信息的位置并知道要释放多少内存。因此,当传递指向在 DLL 中分配的内存的指针时,free
它不会知道要释放多少内存。
原则上,库函数返回的指针可以在同一台机器上运行的任何程序中使用吗?
char s[11];
if (scanf_s("%[a-z]s", s, 10)) printf("String1: %s\n", s);
if (scanf_s("%[a-z]s", s, 10)) printf("String2: %s\n", s);
输出:
abcABC
String1: abc
这种行为的原因是什么scanf_s
以及如何解决?如果您不使用字符集修饰符,则一切正常:
char s[11];
if (scanf_s("%s", s, 10)) printf("String1: %s\n", s);
if (scanf_s("%s", s, 10)) printf("String2: %s\n", s);
输出:
abc
String1: abc
XYZ
String2: XYZ
比如有这样一个结构:
struct FooStructure
{
WORD Field1;
WORD Field2;
WORD Field3;
}
其中所有字段的大小为 2 个字节。如果在程序执行期间发现Field2
没有足够的空间来存储字段中的值并且您不需要 2 个字节,而是 4 个字节(DWORD
),该怎么办。同时,在DWORD
这种情况下立即使用它并留有余量不是一种选择,因为。然后将数据划分为结构的字段,然后按顺序进入内存。
更具体地说,任务是解析 .NET 托管模块的元数据表。由于这些表使用了很多其他元数据流中不同类型对象的索引,而这些索引可以是2字节或4字节,因此使用结构进行元数据处理是有问题的。
我正在尝试在 Windows 上构建 Caffe,以便以后在我的 C++ 项目中使用。按照GitHub 上的说明进行操作。
我已经安装了Visual Studio 2017,cl.exe文件的路径如下:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.16.27023\bin\Hostx64\x64\ cl.exe
还安装了 CMake 版本 3.14.3。
执行 build_win.cmd 脚本时,出现错误:
CMake 错误:无法创建命名生成器 Visual Studio 14 2017 Win64。
完整输出:
C:\Users\Lenovo\Desktop\caffe>scripts\build_win.cmd
Системе не удается найти указанный диск.
Системе не удается найти указанный диск.
INFO: ============================================================
INFO: Summary:
INFO: ============================================================
INFO: MSVC_VERSION = 14
INFO: WITH_NINJA = 0
INFO: CMAKE_GENERATOR = "Visual Studio 14 2017 Win64"
INFO: CPU_ONLY = 1
INFO: CUDA_ARCH_NAME = Auto
INFO: CMAKE_CONFIG = Release
INFO: USE_NCCL = 0
INFO: CMAKE_BUILD_SHARED_LIBS = 0
INFO: PYTHON_VERSION = 2
INFO: BUILD_PYTHON = 0
INFO: BUILD_PYTHON_LAYER = 1
INFO: BUILD_MATLAB = 0
INFO: PYTHON_EXE = "python"
INFO: RUN_TESTS = 0
INFO: RUN_LINT = 0
INFO: RUN_INSTALL = 0
INFO: ============================================================
Системе не удается найти указанный путь.
CMake Error: Could not create named generator Visual Studio 14 2017 Win64
Generators
Visual Studio 16 2019 = Generates Visual Studio 2019 project files.
Use -A option to specify architecture.
* Visual Studio 15 2017 [arch] = Generates Visual Studio 2017 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 14 2015 [arch] = Generates Visual Studio 2015 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 12 2013 [arch] = Generates Visual Studio 2013 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 11 2012 [arch] = Generates Visual Studio 2012 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 10 2010 [arch] = Generates Visual Studio 2010 project files.
Optional [arch] can be "Win64" or "IA64".
Visual Studio 9 2008 [arch] = Generates Visual Studio 2008 project files.
Optional [arch] can be "Win64" or "IA64".
Borland Makefiles = Generates Borland makefiles.
NMake Makefiles = Generates NMake makefiles.
NMake Makefiles JOM = Generates JOM makefiles.
Green Hills MULTI = Generates Green Hills MULTI files
(experimental, work-in-progress).
MSYS Makefiles = Generates MSYS makefiles.
MinGW Makefiles = Generates a make file for use with
mingw32-make.
Unix Makefiles = Generates standard UNIX makefiles.
Ninja = Generates build.ninja files.
Watcom WMake = Generates Watcom WMake makefiles.
CodeBlocks - MinGW Makefiles = Generates CodeBlocks project files.
CodeBlocks - NMake Makefiles = Generates CodeBlocks project files.
CodeBlocks - NMake Makefiles JOM
= Generates CodeBlocks project files.
CodeBlocks - Ninja = Generates CodeBlocks project files.
CodeBlocks - Unix Makefiles = Generates CodeBlocks project files.
CodeLite - MinGW Makefiles = Generates CodeLite project files.
CodeLite - NMake Makefiles = Generates CodeLite project files.
CodeLite - Ninja = Generates CodeLite project files.
CodeLite - Unix Makefiles = Generates CodeLite project files.
Sublime Text 2 - MinGW Makefiles
= Generates Sublime Text 2 project files.
Sublime Text 2 - NMake Makefiles
= Generates Sublime Text 2 project files.
Sublime Text 2 - Ninja = Generates Sublime Text 2 project files.
Sublime Text 2 - Unix Makefiles
= Generates Sublime Text 2 project files.
Kate - MinGW Makefiles = Generates Kate project files.
Kate - NMake Makefiles = Generates Kate project files.
Kate - Ninja = Generates Kate project files.
Kate - Unix Makefiles = Generates Kate project files.
Eclipse CDT4 - NMake Makefiles
= Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - MinGW Makefiles
= Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - Ninja = Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - Unix Makefiles= Generates Eclipse CDT 4.0 project files.
ERROR: Configure failed
脚本内容:https ://pastebin.com/XqZfP18u
如何修复错误?
PS:我正在做一个仅限 CPU 的构建。我没有安装任何CUDA。
define('chart', ['l/graph'], function (Graph) {
...
return React.createClass({
displayName: 'Chart',
render: function() {
...
}
});
});
这段代码创建了一个 React 组件Chart
。告诉我如何render
使用 JS 覆盖这个组件的方法?
PS:我不懂JS,请帮忙。