首先,在实际问题之前的一个小免责声明:
我知道关于
sizeof
运算符和Marshal.SizeOf<T>
方法之间的区别有很多关闭/重复的问题,我确实理解了两者之间的区别.这里我说的SizeOf<T>
是新Unsafe
课程中的方法
所以,我不确定我是否理解这两个操作之间的实际区别,特别是在结构/类上使用该方法时是否存在特定的差异.
该sizeof
运营商需要一个类型名称,返回的数量管理字节它应该占用分配时(即一个Int32
将返回4,例如).
Unsafe.SizeOf<T>
另一方面,该方法在IL中实现,就像类中的所有其他方法一样Unsafe
,并且在这里看代码是它的作用:
.method public hidebysig static int32 SizeOf<T>() cil managed aggressiveinlining
{
.custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 )
.maxstack 1
sizeof !!T
ret
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我没有错,代码只是调用sizeof !!T
wich与sizeof(T)
调用sizeof
带有类型名称的运算符相同T
,那么它们中的两个是否完全等价?
另外,我看到该方法也在NonVersionableAttribute
第一行中分配了一个无用的对象(the ),所以这不会导致少量的内存被堆分配吗?
我的问题是:
是否可以肯定地说这两种方法是完全等价的,因此使用经典
sizeof
算子更好,因为这也避免了在SizeOf<T>
方法中分配该属性?这被SizeOf<T>
添加到方法Unsafe
类只是为了方便,在这一点?
我正在从UWP应用程序(C#,使用.NET Native编译)中读取一些崩溃报告,并且我很难理解堆栈跟踪中使用的确切语法/格式.我尝试在互联网上寻找一些指南,但我没有想出任何有用的东西.
这里有一些例子:
1)
MyProject.ViewModels.SomeViewModel.<OnLogin>d__69.MoveNext()
Run Code Online (Sandbox Code Playgroud)
OnLogin
是一个方法的名称SomeViewModel
,为什么它在尖括号内?是"ClassName".<"MethodName>..."
指示实例方法的常用方法吗?await
调用之间将每个代码块转换为匿名方法,并使用continuation调度它们,所以我猜这d__69
表示当前方法中的异步延续.
await
调用,所以我猜这些数字不是顺序的.是否有可能从堆栈跟踪中的该数字中找出原始方法中的确切部分?MoveNext()
最后那个方法是什么?它需要什么样的类型?2)
MyProject.UserControls.SomeControl.<.ctor>b__0_0
Run Code Online (Sandbox Code Playgroud)
.ctor
代表对象构造函数,并查看我发现的代码,它b__0_0
代表构造函数中添加的匿名事件处理程序,如下所示:SomeEvent += (s, e) => Foo();
.
0_1
,1_0
或其他什么?3)我有这个方法:
// Returns a Task that immediately throws when awaited, as soon as the token is cancelled
public static Task<T> GetWatchedTask<T>(this Task<T> awaitableTask, CancellationToken token)
{
return awaitableTask.ContinueWith(task => task.GetAwaiter().GetResult(), token);
}
Run Code Online (Sandbox Code Playgroud)
我有这个堆栈跟踪:
MyProject.Helpers.Extensions.TasksExtensions.<>c__3$1<System.__Canon>.<GetWatchedTask>b__3_0($Task$1<__Canon> task)
Run Code Online (Sandbox Code Playgroud)
我正在寻找一些关于如何在WinRT中创建自定义控件的教程,我有一个问题.
假设我想创建一个包含一些东西的简单控件,比如左边是图像的Grid,右边是几个TextBlocks.
我的意思是,简单的事情:
<Grid Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*"/>
<ColumnDefinition Width="0.7*"/>
</Grid.ColumnDefinitions>
<Image Source"/Assets/someRandomImage.png"/>
<StackPanel Grid.Column="1"
VerticalAlignment="Center">
<TextBlock Text="Some text"
Margin="10,0,10,0"
FontSize="24"
FontWeight="SemiLight"
TextTrimming="CharacterEllipsis"/>
<TextBlock Text="Some random description..."
Margin="10,5,10,0"
FontSize="18"
FontWeight="Light"
Foreground="Gray"
TextWrapping="Wrap"
TextTrimming="CharacterEllipsis"/>
</StackPanel>
</Grid>
Run Code Online (Sandbox Code Playgroud)
我会用这个内容创建一个UserControl,所以当我正在处理它的UI时,我将能够在XAML Designer中看到它,并且我将在UserControl代码中添加所有Properties和DependencyProperties.
然后我看到另一种方法是使用Template控件,所以我必须创建一个继承自Control类的类,然后使用上面的XAML代码作为模板并将其应用于自定义控件并添加所有其余的逻辑在那里.
当然,我还必须将x:Name属性添加到控件中的一些UIElements以便能够与它们进行交互,但是你明白了.
我想知道,使用这两种方法中的任何一种方法都可以,或者更好地使用一种方法,为什么呢?此外,我喜欢使用UserControls,因为我可以在Designer窗口中看到它们,而我无法使用模板执行此操作,我必须运行应用程序并创建控件的实例以查看它是什么实际上看起来像.
感谢您的帮助,我想我不是唯一一个有这种疑问的人,所以我希望这个问题能够帮助其他人:D
塞尔吉奥
我试图了解在调用更新我的ViewModel的异步方法时使用的最佳方法是什么.现在,让我说我有这样的事情:
视图:
private async void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
//Call my ViewModel method to update the data the UI is bound to
}
Run Code Online (Sandbox Code Playgroud)
视图模型:
public async Task loadData()
{
this.Source = await loadStuffFromDatabaseAsync();
}
Run Code Online (Sandbox Code Playgroud)
现在,我不确定应该使用以下哪种方法:
1)在我的LoadState方法中,使用:
await Task.Run(async () => { await ViewMode.loadData(); });
Run Code Online (Sandbox Code Playgroud)
2)使用Task.Run而不等待Action内的loadData方法:
await Task.Run(() => { ViewModel.loadData(); });
Run Code Online (Sandbox Code Playgroud)
3)调用我的loadData方法:
await ViewModel.loadData().ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)
4)调用loadData方法而不在我的View类中等待它,并在我的loadData方法中使用Task.Run:
视图:
private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
ViewModel.loadData();
}
Run Code Online (Sandbox Code Playgroud)
视图模型:
public async void loadData()
{
await Task.Run(async () => …
Run Code Online (Sandbox Code Playgroud) 我正在使用新Span<T>
类型重写我的一些扩展方法,并且我无法找到正确固定通用实例的方法,以便能够使用并行代码来处理它.
例如,考虑这种扩展方法:
public static unsafe void Fill<T>(this Span<T> span, [NotNull] Func<T> provider) where T : struct
{
int
cores = Environment.ProcessorCount,
batch = span.Length / cores,
mod = span.Length % cores,
sizeT = Unsafe.SizeOf<T>();
//fixed (void* p0 = &span.DangerousGetPinnableReference()) // This doesn't work, can't pin a T object
void* p0 = Unsafe.AsPointer(ref span.DangerousGetPinnableReference());
{
byte* p = (byte*)p0; // Local copy for the closure
Parallel.For(0, cores, i =>
{
byte* start = p + i * batch * …
Run Code Online (Sandbox Code Playgroud) 我注意到C#8.0编译器为IDisposable
使用C#8.0使用声明声明的捕获变量构建闭包类的方式有所不同,这与经典的using声明声明的变量不同。
考虑这个简单的类:
public class DisposableClass : IDisposable
{
public void Dispose() { }
}
Run Code Online (Sandbox Code Playgroud)
和此示例代码:
public void Test()
{
using var disposable1 = new DisposableClass();
using var disposable2 = new DisposableClass();
Action action = () => Console.Write($"{disposable1}{disposable2}");
}
Run Code Online (Sandbox Code Playgroud)
编译器生成以下代码:
[CompilerGenerated]
private sealed class <>c__DisplayClass0_0
{
public DisposableClass disposable1;
public DisposableClass disposable2;
internal void <Test>b__0()
{
Console.Write(string.Format("{0}{1}", disposable1, disposable2));
}
}
public void Test()
{
<>c__DisplayClass0_0 <>c__DisplayClass0_ = new <>c__DisplayClass0_0();
<>c__DisplayClass0_.disposable1 = new DisposableClass();
try
{
<>c__DisplayClass0_.disposable2 = new …
Run Code Online (Sandbox Code Playgroud) 因此,我在使用UWP应用程序时经常使用的模式是使用SemaphoreSlim
实例来避免竞争条件(我不喜欢使用lock
它,因为它需要一个额外的目标对象,并且它不会异步锁定).
一个典型的代码片段如下所示:
private readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1);
public async Task FooAsync()
{
await Semaphore.WaitAsync();
// Do stuff here
Semaphore.Release();
}
Run Code Online (Sandbox Code Playgroud)
随着更多的try/finally
围绕整个事情块,如果之间的代码可能崩溃,但我想保持信号灯工作正常.
为了减少样板,我尝试编写一个包装类,它具有相同的行为(包括try/finally
位),所需的代码更少.我也不想使用a delegate
,因为每次都会创建一个对象,我只是想减少我的代码而不改变它的工作方式.
我想出了这个课程(为简洁起见,删除了评论):
public sealed class AsyncMutex
{
private readonly SemaphoreSlim Semaphore = new SemaphoreSlim(1);
public async Task<IDisposable> Lock()
{
await Semaphore.WaitAsync().ConfigureAwait(false);
return new _Lock(Semaphore);
}
private sealed class _Lock : IDisposable
{
private readonly SemaphoreSlim Semaphore;
public _Lock(SemaphoreSlim semaphore) => Semaphore = semaphore;
void IDisposable.Dispose() => Semaphore.Release(); …
Run Code Online (Sandbox Code Playgroud) 我遇到了VS Designer的这个问题,无法使用它.它发生的是我正在编辑我的XAML代码,VS Designer会在某些时候抛出异常,使用如下的StackTrace:
InvalidOperationException:属性"MyObject.MyProperty"没有get方法
堆栈跟踪:
at Microsoft.Expression.DesignModel.Metadata.ClotProperty.Exign.GetVolue.Metadata.LetClpertProperty.PeritMetl.MetadataMetl上的Microsoft.Expression.DesignModel.Metadata.ClrPropertyRempleStep.GetValue(Object valueToInspect)中的Microsoft.Expression.DesignModel.Metadata.LocalClrPropertyImplementation.GetValue(Object target).对象&值,ReferenceStep referenceStep在[...]的Microsoft.Expression.DesignModel.Metadata.PropertyReference.PartialGetValue(对象目标,Int32 initialStepIndex,Int32 finalStepIndex)上的,对象目标)
...至少还有50行.
有问题的财产是这样的:
private bool _MyProperty = true;
public bool MyProperty
{
set
{
if (_MyProperty != value)
{
// Do a few things here
this._MyProperty = value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,这很好用,我的项目中有很多这样的东西,VS以前从未打扰过我.如果我再次尝试关闭并打开VS,它会让我工作一段时间,然后它最终会再次开始抛出这个错误.
我尝试从编译>清洁解决方案清理解决方案,它不起作用.
我真的不知道这里有什么问题.我的意思是,我在2个月前创建了这个属性,为什么VS现在只告诉我?
有没有修复此问题,或者我是否必须在我创建的每个参数中手动添加所有这些无用的get/set方法?
我正在我的UWP应用程序中设计一个ComboBox,我正在尝试为控件中缺少的下拉动画提供解决方案.
看起来周年纪念更新删除了打开/关闭动画,我的意思是,由于某些原因,它们仍然在设置应用程序中播放,但我不再在我自己的应用程序,计算器或任何其他编译的UWP应用程序中看到它们对于Windows 10 14393.
这是我在ComboBox模板中看到的:
<VisualStateGroup x:Name="DropDownStates">
<VisualState x:Name="Opened">
<Storyboard>
<SplitOpenThemeAnimation OpenedTargetName="PopupBorder"
ClosedTargetName="ContentPresenter"
OffsetFromCenter="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOffset}"
OpenedLength="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOpenedHeight}"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Closed">
<Storyboard>
<SplitCloseThemeAnimation OpenedTargetName="PopupBorder"
ClosedTargetName="ContentPresenter"
OffsetFromCenter="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOffset}"
OpenedLength="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOpenedHeight}"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
Run Code Online (Sandbox Code Playgroud)
这些SplitOpenThemeAnimation
动画并不是真正的动画,因为它们的行为就像一个制定者,它们的效果立竿见影,根本没有动画.
我想知道是否有一种简单的方法来恢复以前的动画(也许我只是缺少一个简单的选项/参数来添加到XAML中?)而不必手动弄乱模板并编写我自己的剪辑/变换动画,这是我不想在这里做的事情,因为MS应该在未来的版本中再次更改模板,我已经做了所有的事情.
这里有什么建议?谢谢!
编辑:目前这是我正在使用的解决方法,但我希望有一些东西可以像原始动画那样保持幻灯片/剪辑动画.
<VisualState x:Name="Opened">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Popup"
Storyboard.TargetProperty="Opacity"
From="0"
To="1"
Duration="0:0:0.2">
<DoubleAnimation.EasingFunction>
<CircleEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="PopupTransform"
Storyboard.TargetProperty="(TranslateTransform.Y)"
From="-20"
To="0"
Duration="0:0:0.2">
<DoubleAnimation.EasingFunction>
<CircleEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<!--Original SplitOpenAnimation here-->
</Storyboard>
Run Code Online (Sandbox Code Playgroud)
我一直在寻找一种从2D矩阵中提取切片的方法,而无需实际重新分配复制内容,以及
public static Span<float> Slice([NotNull] this float[,] m, int row)
{
if (row < 0 || row > m.GetLength(0) - 1) throw new ArgumentOutOfRangeException(nameof(row), "The row index isn't valid");
return Span<float>.DangerousCreate(m, ref m[row, 0], m.GetLength(1));
}
Run Code Online (Sandbox Code Playgroud)
我用这个简单的单元测试检查了这个方法,显然它可以工作:
[TestMethod]
public void Foo()
{
float[,] m =
{
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 9.5f, 10, 11 },
{ 12, 13, 14.3f, 15 }
};
Span<float> s = m.Slice(2);
var copy = s.ToArray();
var …
Run Code Online (Sandbox Code Playgroud)