首先请注意,此问题未标记为winforms或wpf或其他任何GUI特定的.这是故意的,你很快就会看到.
第二,对不起,如果这个问题有点长.我尝试将各种各样的信息汇集在一起,以便提供有价值的信息.然而,我的问题正好在"我想知道的事情"之下.
我的任务是最终了解.NET提供的在特定线程上调用委托的各种方法.
我正在寻找最通用的方法(不是Winforms或WPF特定的)来调用特定线程上的委托.
或者,换句话说:我会感兴趣的是,以及如何做各种各样的方式(例如通过WPF Dispatcher)相互利用; 也就是说,如果所有其他人都使用了一种用于跨线程委托调用的通用机制.
有很多与此主题相关的课程; 其中:
SynchronizationContext (in System.Threading)
如果我不得不猜测,那将是最基本的一个; 虽然我不明白它到底是做什么,也不知道它是如何使用的.
AsyncOperation&(in )
这些似乎是包装.不知道如何使用它们.AsyncOperationManager System.ComponentModelSynchronizationContext
WindowsFormsSynchronizationContext (in System.Windows.Forms)
的子类SynchronizationContext.
ISynchronizeInvoke (in System.ComponentModel)
由Windows窗体使用.(Control该类实现了这个.如果我不得不猜测,我会说这个实现可以使用WindowsFormsSynchronizationContext.)
Dispatcher&(in )
似乎后者是另一个子类,前者代表它.DispatcherSynchronizationContext System.Windows.ThreadingSynchronizationContext
有些线程有自己的消息循环,还有消息队列.
(MSDN页面关于消息和消息队列有一些介绍消息循环如何在系统级工作的背景信息,即消息队列作为Windows API.)
我可以看到如何为具有消息队列的线程实现跨线程调用.使用Windows API,您可以将消息放入特定线程的消息队列PostThreadMessage,其中包含调用某个委托的指令.消息循环 - 在该线程上运行 - 最终将到达该消息,并且将调用该委托.
根据我在MSDN上阅读的内容,线程不会自动拥有自己的消息队列.消息队列将变为可用,例如当线程创建窗口时.没有消息队列,线程没有消息循环是没有意义的.
那么,当目标线程没有消息循环时,是否可以进行跨线程委托调用?比方说,在.NET控制台应用程序中?(从这个问题的答案来看,我认为控制台应用确实不可能.)
.net winapi multithreading system.componentmodel synchronizationcontext
我认为自己是一个经验丰富的.NET开发人员,但我几乎从未在System.ComponentModel命名空间中直接使用类型.(我已经实现了一些自定义属性并通过反射消耗它们).
在什么样的场景中,诸如Component,Container,PropertyDescriptor,TypeDescriptor,License和TypeConverter等类型最有用?
在谈论"设计者"时,我经常看到System.ComponentModel,例如Visual Studio中提供的那些.
例如,当您想要使用漂亮的可视化设计器(例如自定义属性等)构建自定义控件时,这些类型是否有用?或者我也可以在更通用的代码中使用它们吗?
首先,我不得不说我要谈谈System.ComponentModel.Component.
您知道,我知道,.NET Component Model提供能力(通过站点服务)来定义单独的Components,因此它们可以以松散耦合的方式相互通信,并且每个都Component可以轻松替换.
但我要说的是,我能以其他方式做到这一点:我的意思是,如果我在正确的设计SW Object Oriented Programming的方式,我可以用的手段Abstract classes,Interfaces等实现上述所有的功能/互操作性.
那么为什么和何时我要依靠组件模型?
是什么之间的区别System.ComponentModel.BindingList方法Add(object)和AddNew()?MSDN文档说明了这一点:
看起来这两种方法都将一个项目添加到集合中,但是Add(object)一次性完成,而AddNew()稍微复杂一些.我的测试Add(object)似乎有效,但我想知道我是否使用了正确的方法.
那么这些方法有什么区别呢?
bindinglist inotifypropertychanged system.componentmodel c#-4.0
我正在将一个名为“Bridge”的 Azure 函数部署到 Azure,目标是 .NET 6。该项目引用了我编写的一个名为“DBLibrary”的类库,该库目标是 .NET Standard 2.1。Azure Function 可以在我的 PC 上本地运行,不会出现运行时错误。
当我将 Azure Function 发布到 Azure 时,我在 Azure 门户中看到“函数运行时错误”,其中显示:
无法加载文件或程序集“System.ComponentModel,Version=6.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a”。该系统找不到指定的文件。
我不直接针对 System.ComponentModel,并且我没有看到任何 nuget feed 中提供的“System.ComponentModel”的 nuget 包版本 6.0.0。为什么 Azure 函数要查找此版本 6.0.0 的 System.ComponentModel?如果该版本确实存在,为什么 Azure Functions 找不到它?
以下是“Bridge”Azure Function 的 csproj 的相关部分:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
<PackageReference Include="Microsoft.Extensions.Azure" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DBLibrary\DBLibrary.csproj" />
</ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
以下是 Azure Function 项目引用的“DBLibrary”类库的 csproj 的相关部分:
<Project …Run Code Online (Sandbox Code Playgroud) azure system.componentmodel .net-core azure-functions .net-6.0
我在理解容器/组件模型如何在C#中相互交互时遇到了一些困难.我得到了Component如何包含一个Site对象,它包含有关Container和Component的信息.但是,假设我有以下代码:
using System;
using System.ComponentModel;
public class Entity : Container {
public string Foo = "Bar";
}
public class Position : Component {
public int X, Y, Z;
public Position(int X, int Y, int Z){
this.X = X;
this.Y = Y;
this.Z = Z;
}
}
public class Program {
public static void Main(string[] args) {
Entity e = new Entity();
Position p = new Position(10, 20, 30);
e.Add(p, "Position");
}
}
Run Code Online (Sandbox Code Playgroud)
这没有问题,它定义了容器(实体)和包含在其中的组件(位置).
但是,如果我调用p.Site.Container它,它将返回Entity,但作为IContainer.也就是说,(Console.WriteLine(p.Site.Container as Entity).Foo);如果我想访问Foo …
我想在运行时动态地将MEF Export属性应用于某个类型,就好像该类型在编译时应用了Export属性一样.
有一个简单的方法吗?
除此之外,是否有一种复杂的方法可以做到这一点?
我正在看这篇文章,它描述了在POCO属性之间进行数据绑定的简单方法:数据绑定POCO属性
Bevan的评论之一包括一个简单的Binder类,可用于完成此类数据绑定.它对我需要的东西很有用,但我想实现Bevan为改进课程所做的一些建议,即:
此外,鉴于按字符串指定属性容易出错,您可以使用Linq表达式和扩展方法.然后而不是写作
Binder.Bind( source, "Name", target, "Name")
Run Code Online (Sandbox Code Playgroud)
你可以写
source.Bind( Name => target.Name);
Run Code Online (Sandbox Code Playgroud)
我很确定我可以处理前三个(尽管可以随意包含这些更改)但我不知道如何使用Linq表达式和扩展方法来编写代码而不使用属性名称字符串.
有小费吗?
以下是链接中的原始代码:
public static class Binder
{
public static void Bind(
INotifyPropertyChanged source,
string sourcePropertyName,
INotifyPropertyChanged target,
string targetPropertyName)
{
var sourceProperty
= source.GetType().GetProperty(sourcePropertyName);
var targetProperty
= target.GetType().GetProperty(targetPropertyName);
source.PropertyChanged +=
(s, a) =>
{
var sourceValue = sourceProperty.GetValue(source, null);
var targetValue = targetProperty.GetValue(target, null);
if (!Object.Equals(sourceValue, targetValue))
{
targetProperty.SetValue(target, sourceValue, null);
}
};
target.PropertyChanged +=
(s, a) =>
{
var sourceValue = …Run Code Online (Sandbox Code Playgroud) 更多可用性问题.我正在构建一个大的MVVM应用程序,我发现自己在这个地方复制/修改这段代码:
public NodeKind Kind
{
get { return (NodeKind)this.GetValue(KindProperty); }
set { this.SetValue(KindProperty, value); }
}
public static readonly DependencyProperty KindProperty = DependencyProperty.Register(
"Kind", typeof(NodeKind), typeof(DashboardNode));
Run Code Online (Sandbox Code Playgroud)
在Visual Studio中有一种方法可以使用快捷方式生成此代码吗?我有Resharper和VS 2015,我找不到自动为我做的命令.
我正在尝试创建一个扩展方法,它将返回一个仅List<string>包含Description给定的设置值的所有属性[Flags] Enum.
例如,假设我在C#代码中声明了以下枚举:
[Flags]
public enum Result
{
[Description("Value 1 with spaces")]
Value1 = 1,
[Description("Value 2 with spaces")]
Value2 = 2,
[Description("Value 3 with spaces")]
Value3 = 4,
[Description("Value 4 with spaces")]
Value4 = 8
}
Run Code Online (Sandbox Code Playgroud)
然后将变量设置为:
Result y = Result.Value1 | Result.Value2 | Result.Value4;
Run Code Online (Sandbox Code Playgroud)
所以,我想要创建的调用将是:
List<string> descriptions = y.GetDescriptions();
Run Code Online (Sandbox Code Playgroud)
最终结果将是:
descriptions = { "Value 1 with spaces", "Value 2 with spaces", "Value 4 with spaces" };
Run Code Online (Sandbox Code Playgroud)
我已经创建了一个扩展方法,用于获取Enum 的单个描述属性,该属性不能设置多个标记,这些标记位于以下行中:
public …Run Code Online (Sandbox Code Playgroud) .net ×5
c# ×4
components ×2
.net-6.0 ×1
.net-core ×1
azure ×1
bindinglist ×1
c#-4.0 ×1
composition ×1
data-binding ×1
enums ×1
mef ×1
mvvm ×1
poco ×1
reflection ×1
winapi ×1
wpf ×1