我有一个非托管的C++ DLL,我的.NET应用程序通过p/invoke使用它.我需要从这个DLL的方法相当耗时,我想并行化方法调用.问题是它使用了一堆静态和全局变量,因此它不是线程安全的(并且不能更改).我的计划是通过并行调用多个AppDomain中的非托管DLL来克服这个非线程安全问题.
我可以从多个AppDomain中调用非托管代码而不会出现任何问题,只要我不并行执行,但只要我并行调用,我就会得到一个AccessViolationException.我正在使用Parallel.For()来进行并行调用.
是否可以通过简单地从多个AppDomain进行调用来使非线程安全的非托管DLL"线程安全"?
我正在使用.NET 4.0 Beta 2附带的.NET Chart Control库在后台线程上创建图像并将其保存到磁盘.我没有在屏幕上显示图表,只是创建一个图表,将其保存到磁盘并销毁它.像这样的东西:
public void GeneratePlot(IList<DataPoint> series, Stream outputStream) {
using (var ch = new Chart()) {
ch.ChartAreas.Add(new ChartArea());
var s = new Series();
foreach (var pnt in series) s.Points.Add(pnt);
ch.Series.Add(s);
ch.SaveImage(outputStream, ChartImageFormat.Png);
}
}
Run Code Online (Sandbox Code Playgroud)
创建和保存每个图表大约需要300到400毫秒.我可能有数百个图表要创建,所以我想我会用它Parallel.For()来并行化这些任务.我有一个8核机器,但是,当我尝试一次创建4个图表时,我的图表创建/保存时间增加到800到1400毫秒,几乎所有这些都消耗了Chart.SaveImage.
我认为这可能是磁盘I/O的限制,所以为了测试我将最后一行更改为:
ch.SaveImage(Stream.Null, ChartImageFormat.Png);
Run Code Online (Sandbox Code Playgroud)
即使写入空流,性能仍然大致相同(800 - 1400毫秒).
我不应该在与这个库并行的后台线程上创建图像,或者我做错了什么?
谢谢
编辑:添加完整代码示例
只需更改传递给的标志CreateCharts()即可测试并行与串行.
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms.DataVisualization.Charting;
namespace ConsoleChartTest
{
class Program
{
public static void GeneratePlot(IEnumerable<DataPoint> series, Stream …Run Code Online (Sandbox Code Playgroud) 从版本控制软件中检查代码以执行持续集成或每晚构建时,您通常会做什么?你是1)拉最新的代码,还是2)拉一些代表开发人员最新代码的标签(即FUNCTIONAL)?
我想这个答案取决于人们通常如何使用他们的配置管理存储库.您是否打算只存储"完整"的代码.如果是这种情况,如果开发人员正在处理任务一周左右,他/她将无法检查任何内容,直到任务完成.但是,如果持续集成服务器只是由一个众所周知的标签拉动而不是拉动最新代码,那么这将允许开发人员非常频繁地检查代码,因为他们正在努力存储他们正在进行的工作的历史.然后,一旦他们对变化感到满意,他们就可以使用FUNCTIONAL标记标记新代码.
只是想知道最佳实践.
谢谢
假设我有一些域对象需要使用自定义二进制格式进行序列化/打包,以便它们可以通过套接字发送到外部进程。我的第一直觉是创建一个接口来表示可以打包成这种二进制格式的任何对象。
public interface IPackable
{
byte[] Pack();
}
Run Code Online (Sandbox Code Playgroud)
然后我的域对象(如Entity,State,Vector,等)将分别实现这个接口。这类似于 .NET 和 Java 中默认序列化的工作方式。
public class Vector : IPackable
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
// other operators and methods...
public byte[] Pack
{
MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(X);
writer.Write(Y);
writer.Write(Z);
return stream.ToArray();
}
Run Code Online (Sandbox Code Playgroud)
然而,我对设计原则了解得越多(例如 SOLID 的单一职责原则),我就越认为我应该创建一个单独的类来打包我的域对象。
我可以看到两者的优点和缺点。大家怎么看?如果答案是创建一个单独的类来打包域对象,我是否应该为每个域对象创建一个单独的打包程序(例如EntityPacker,StatePacker, …
我有一个 Flutter 应用程序,用户可以在其中发布帖子并将帖子标记为属于一个组。帖子存储在一个全局集合中,每个帖子都有一个Post.groupId字段:
/posts/{postId}
Run Code Online (Sandbox Code Playgroud)
根据我的 Firestore 安全规则和查询,如果用户在帖子被标记的组(即帖子的groupId字段)中,则只允许他们阅读帖子。批准的组用户存储在:
/groups/{groupId}/users/{userId}
Run Code Online (Sandbox Code Playgroud)
我可以查询来自特定用户组的帖子,例如:
_firestore.collection('posts').where('groupId', isEqualTo: 'groupA')...
Run Code Online (Sandbox Code Playgroud)
以上这些都正常工作。
我正在尝试进行改进,其中可以在多个组中而不是一个组中标记帖子,因此我将单个Post.groupId字段替换为Post.groupIds数组。如果用户是来自 的任何组的成员,则他/她应该能够阅读帖子Post.groupIds。我尝试使用 Flutter 应用程序中的以下查询阅读所有标记为特定组的帖子:
_firestore.collection('posts').where('groupIds', arrayContains: 'groupA')...
Run Code Online (Sandbox Code Playgroud)
Missing or insufficient permissions对于这些安全规则,我不断收到以下异常:
match /posts/{postId} {
allow read: if canActiveUserReadAnyGroupId(resource.data.groupIds);
}
function isSignedIn() {
return request.auth != null;
}
function getActiveUserId() {
return request.auth.uid;
}
function isActiveUserGroupMember(groupId) {
return isSignedIn() &&
exists(/databases/$(database)/documents/groups/$(groupId)/users/$(getActiveUserId()));
}
function canActiveUserReadAnyGroupId(groupIds) {
return groupIds != null && (
(groupIds.size() >= 1 && isActiveUserGroupMember(groupIds[0])) || …Run Code Online (Sandbox Code Playgroud) 将虚拟方法注册为事件处理程序而不是注册委托给虚拟方法的私有方法是否有任何问题?我更喜欢选项 1(这似乎有效),但我想确保它以后不会咬我。
选项1
public class Controller1
{
public Controller1(EventNotifier eventNotifier)
{
eventNotifier.ImportantEvent += OnEventNotifierImportantEvent;
}
protected virtual void OnEventNotifierImportantEvent(object sender, EventArgs e)
{
}
}
Run Code Online (Sandbox Code Playgroud)
选项 2
public class Controller2
{
public Controller2(EventNotifier eventNotifier)
{
eventNotifier.ImportantEvent += eventNotifier_OnImportantEvent;
}
private void eventNotifier_OnImportantEvent(object sender, EventArgs eventArgs)
{
OnEventNotifierImportantEvent(sender, eventArgs);
}
protected virtual void OnEventNotifierImportantEvent(object sender, EventArgs e)
{
}
}
Run Code Online (Sandbox Code Playgroud) 我经常听说在调用事件监听器之前解锁所有锁是个好主意,以避免死锁.但是,由于lock {}块可以通过C#中的同一个线程重入,是否可以从锁定块调用事件,或者是否需要复制相关的状态数据并在锁定块外部调用事件?
如果没有,请举例说明从lock {}块内调用事件何时出现问题.
谢谢
我的Flutter应用程序从ScrollController要控制的页面离开时抛出了异常(将ScrollController附加到多个滚动视图)NestedScrollView,但我不确定自己在做什么错。
我用下面的简单示例重新创建了异常。我可以从导航FirstPage到SecondPage(也可以向后导航)就好了,但是当我从导航SecondPage到ThirdPage异常时,会引发异常。该SecondPage页面包含我CollapsingAppBarPage认为有问题的自定义窗口小部件。CollapsingAppBarPage在此示例中被简化,但是在我的真实应用中,它会根据滚动位置更改组件的颜色/大小。在此示例中,当_scrollController.offset导航开始到时会在发生时发生异常ThirdPage。另外,我知道FirstPage和ThirdPage可能是Stateless而不是StatefulWidgets,但我想使其尽可能与我的应用程序一样。这是我充分工作的例子。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: FirstPage(),
);
}
}
class FirstPage extends StatefulWidget {
@override
_FirstPageState createState() => _FirstPageState();
}
class _FirstPageState extends State<FirstPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("First Page"),
),
body: …Run Code Online (Sandbox Code Playgroud)