我最近使用async/await模式将一些代码更改为异步.
此代码现在正在创建一个例外:
private async void Refresh(object stateInfo)
{
await Task.Factory.StartNew(HydrateServerPingDtoList);
// more code here
}
private void HydrateServerPingDtoList()
{
// more code here.
// Exception occurs on this line:
this._serverPingDtoList.Add(new ServerPingDto() { ApplicationServer = server });
}
Run Code Online (Sandbox Code Playgroud)
例外:
这种类型的CollectionView不支持从与Dispatcher线程不同的线程更改其SourceCollection.
_serverPingDtoList是WPF绑定属性的支持字段.由于我认为async-await保留了同步上下文,为什么我会收到此错误?
我对我的应用程序进行了更改,以在应用程序打开时在后台线程上加载数据(使用异步/等待)。现在,在应用程序完全加载后,当尝试更新绑定属性时,我收到此异常:
类型“System.NotSupportedException”的第一次机会异常出现在PresentationFramework.dll中
附加信息:这种类型的 CollectionView 不支持从与 Dispatcher 线程不同的线程更改其 SourceCollection。
在异步/等待更改首先更新该属性之前,此代码正在运行。我尝试在代码中添加 Dispatcher.Invoke() ,但出现了相同的错误:
System.Windows.Application.Current.Dispatcher.Invoke(() =>
{
this._customVariableGroups[index] = savedGroup;
});
Run Code Online (Sandbox Code Playgroud)
由于该字段最初是在后台线程上更新的,这是否会导致从主线程更新它时出现问题?请注意,在 Visual Studio 的线程窗口中,此代码在主线程上执行。我不知道还要做什么才能让它发挥作用。
这是字段:
private ObservableCollection<CustomVariableGroup> _customVariableGroups;
Run Code Online (Sandbox Code Playgroud) 我有一些我不理解的行为.我正在使用RavenDB,我正在为每个工作单元使用一个会话:当逻辑类调用RavenDB数据访问层(DAL)时,会创建一个新会话.在DAL中,可以调用其他DAL类和方法,但只使用一个会话.
我不明白的部分是在下面的GetMostRecentByStartTime()方法中使用IEnumerable和List之间的区别.在该方法中,使用List就像显示的一样,这是我的输出:
使用List:
关闭会话之前
的请求数:2 关闭会话之前
的请求数:4 关闭会话之前
的请求数:6 关闭会话之前的请求数:7
注意:会话实际上并未在每个时间关闭; 只在最后一次之后.我们只在完成最初调用的DAL方法时关闭会话.
现在,如果我用IEnumerable替换List的每个实例(这是我做的唯一更改),我得到这个输出:
使用IEnumerable:
关闭会话之前
的请求数:2 关闭会话之前
的请求数:3 关闭会话之前
的请求数:4 关闭会话之前的请求数:27
为什么不同?
另一个问题是,当我在我的应用程序中添加新的InstallationSummary对象时,使用IEnumerable方法增加了请求计数.我不明白为什么.当我使用List方法时,即使添加了更多的InstallationSummary对象,请求计数也保持不变.也有人可以解释一下吗?
public IEnumerable<InstallationSummary> GetMostRecentByStartTime(int numberToRetrieve)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
try
{
return ExecuteQuery<IEnumerable<InstallationSummary>>(() =>
{
List<InstallationSummary> installationSummaries =
QueryAndCacheEtags(session => session.Advanced.LuceneQuery<InstallationSummary>()
.Include(x => x.ApplicationServerId)
.Include(x => x.ApplicationWithOverrideVariableGroup.ApplicationId)
.Include(x => x.ApplicationWithOverrideVariableGroup.CustomVariableGroupId)
.OrderByDescending(summary => summary.InstallationStart)
.Take(numberToRetrieve)).Cast<InstallationSummary>().ToList();
List<string> appServerIds = (from item in installationSummaries select item.ApplicationServerId).ToList();
List<string> appIds = (from item in installationSummaries select item.ApplicationWithOverrideVariableGroup.ApplicationId).ToList();
List<string> …Run Code Online (Sandbox Code Playgroud) 我正在玩AutoResetEvent,我的应用程序没有结束,我想我知道原因:线程仍在运行,因此应用程序不会终止.通常,在Main()我按下一个键后,应用程序终止.但控制台窗口不再关闭.我有一个简单的控制台应用:
private static EventWaitHandle waitHandle = new AutoResetEvent(false);
static void Main(string[] args)
{
AutoResetEventFun();
Console.WriteLine("Press any key to end.");
Console.ReadKey();
waitHandle.Close(); // This didn't cause the app to terminate.
waitHandle.Dispose(); // Nor did this.
}
private static void AutoResetEventFun()
{
// Start all of our threads.
new Thread(ThreadMethod1).Start();
new Thread(ThreadMethod2).Start();
new Thread(ThreadMethod3).Start();
new Thread(ThreadMethod4).Start();
while (Console.ReadKey().Key != ConsoleKey.X)
{
waitHandle.Set(); // Let one of our threads process.
}
}
// There are four of these methods. …Run Code Online (Sandbox Code Playgroud) 我对如何开始为这种方法开始单元测试感到茫然:
public override void ModifyXmlDocument(Foo foo, string nodeToChange, string newValue)
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(foo.XmlPathAndFileName);
XmlElement rootElement = xmlDocument.DocumentElement;
// rest of method (to modify an XML doc) here
}
Run Code Online (Sandbox Code Playgroud)
该方法只是在XML文档中找到元素/节点,并使用用户提供的值进行更新.(该方法比此处显示的方法更复杂.)
我遇到困难的部分是了解如何执行此方法,而不依赖于硬盘.但是xmlDocument.Load()采用文件路径并从磁盘加载文件.在方法结束时,它将更新的文件保存回磁盘.
如何使此方法单元可测试?
这是我的网页:

我试图找出为什么我的列表没有正确显示,但这是另一篇文章。要进行故障排除,我右键单击该页面,然后选择“查看页面源代码”。正如您在下面看到的那样,该人员列表(Adam Kinkaid等)甚至都没有出现。那怎么可能?
页面来源:
<!DOCTYPE html>
<html>
<head>
<title>Presto</title>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="format-detection" content="telephone=no"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="/Content/ie10mobile.css" rel="stylesheet"/>
<link href="/Content/jquery.mobile-1.3.2.css" rel="stylesheet"/>
<link href="/Content/jquery.mobile.structure-1.3.2.css" rel="stylesheet"/>
<link href="/Content/jquery.mobile.theme-1.3.2.css" rel="stylesheet"/>
<link href="/Content/bootstrap.css" rel="stylesheet"/>
<link href="/Content/bootstrap-responsive.css" rel="stylesheet"/>
<link href="/Content/durandal.css" rel="stylesheet"/>
<link href="/Content/toastr.css" rel="stylesheet"/>
<link href="/Content/app.css" rel="stylesheet"/>
<script type="text/javascript">
if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
var msViewportStyle = document.createElement("style");
var mq = "@-ms-viewport{width:auto!important}";
msViewportStyle.appendChild(document.createTextNode(mq));
document.getElementsByTagName("head")[0].appendChild(msViewportStyle);
}
</script>
</head> …Run Code Online (Sandbox Code Playgroud) 这段代码没有await编译:
IEnumerable<PingResponse> pingResponses;
using (var prestoWcf = new PrestoWcf<IPingService>())
{
pingResponses = prestoWcf.Service.GetAllForPingRequest(this.PingRequest);
}
foreach (PingResponse response in pingResponses) { // code here }
Run Code Online (Sandbox Code Playgroud)
这段代码用await,不编译:
IEnumerable<PingResponse> pingResponses;
await Task.Factory.StartNew(() =>
{
using (var prestoWcf = new PrestoWcf<IPingService>())
{
pingResponses = prestoWcf.Service.GetAllForPingRequest(this.PingRequest);
}
});
foreach (PingResponse response in pingResponses) { // code here }
Run Code Online (Sandbox Code Playgroud)
错误是: Use of unassigned local variable 'pingResponses'
为什么引入async/await会导致此问题?
我正在使用反射来扫描文件夹中的所有程序集,以实现实现特定接口并从特定基类派生的类型。代码如下:
foreach (string file in Directory.GetFiles(folder, "*.dll"))
{
Assembly assembly = Assembly.LoadFile(file);
Type foundType = (from type in assembly.GetTypes()
where type.GetInterfaces().Contains(typeof(TInterface))
&& type.BaseType.Name.LeftOf('`') == baseClass.Name.LeftOf('`')
select type).FirstOrDefault();
if (foundType == default(Type)) { continue; }
// Register our type so we don't need to use reflection on subsequent requests.
DependencyContainer.Register(typeof(TInterface), foundType);
return CreateInstance<TInterface>(foundType);
}
Run Code Online (Sandbox Code Playgroud)
在代码审查期间,针对这段代码提出了两个问题。首先,一旦找到匹配的类型,我们将无法缩短循环;如果发现多个匹配类型,则需要遍历每个文件并引发异常。那把我带到这里真正的问题...
代码审查者想知道是否有更好的方法来加载每个文件。出于性能原因,我们想知道是否可以遍历应用程序域中已加载的文件,而不是调用Assembly.LoadFile(file)每个文件。我们认为,为什么要加载每个已加载的文件?这是一个有效的问题吗?这种加载文件的方式与将文件加载到应用程序域中的方式相同吗?什么是遍历每个文件的有效方法,这样我们就不会浪费处理时间?
注意:Assembly.LoadFile()的文档不是很有帮助:
在指定路径上加载程序集文件的内容。
我不确定这是否等同于将文件加载到应用程序域中的方式,还是完全不同的情况。
我正在进行Web API调用,我收到此错误:
405不允许
的方法请求的资源不支持http方法'GET'.
这是电话:
var config = {
url: rootWebApiUrl + '/api/containerMove/allowMultipleBoxesPerMove',
method: 'GET'
};
$http(config)
.then(function (response) {
// code here
}, function (response) {
// code here
});
Run Code Online (Sandbox Code Playgroud)
如果我将HttpGet属性添加到Web API方法,它可以工作:
[HttpGet]
[Route("api/containerMove/allowMultipleBoxesPerMove")]
public bool AllowMultipleBoxesPerMove()
Run Code Online (Sandbox Code Playgroud)
我不明白的是,HttpGet我在同一个Web API控制器上进行的其他调用不需要这样做.这是一个没有HttpGet属性的工作:
var config = {
url: rootWebApiUrl + '/api/containerMove/getBatchRefreshInterval',
method: 'GET'
};
$http(config)
Run Code Online (Sandbox Code Playgroud)
和Web API方法:
[Route("api/containerMove/getBatchRefreshInterval")]
public int GetBatchRefreshInterval()
Run Code Online (Sandbox Code Playgroud)
那么为什么我需要HttpGet一个Web API方法而不是另一个?那些调用和API方法几乎相同.
我收到升级NuGet所需的构建错误:
“ Microsoft.NETCore.Platforms 1.1.0”程序包要求NuGet客户端版本为“ 2.12”或更高版本,但当前的NuGet版本为“ 2.8.60318.667”。
根据我在VS中在线找到的内容,我应该去“工具”>“扩展和更新”。我应该在“更新”选项卡中看到一个升级NuGet的选项。如您所见,该选项不存在:
我的解决方案有一个.nuget文件夹,并且NuGet.exe其中有一个版本为2.8.x 的文件夹。如何升级到2.12?
如果我将代码分成两行,为什么会这样工作:
List<Foo> foos = await _repo.GetFoos();
foos = foos.Where(x => x.FooType != FooType.A).ToList();
Run Code Online (Sandbox Code Playgroud)
但是当我组合它们并Where在同一条线上执行时不起作用?
List<Foo> foos = await _repo.GetFoos().Where(x => x.FooType != FooType.A).ToList();
Run Code Online (Sandbox Code Playgroud)
这会产生一个错误:
Task<List<Foo>>不包含“Where”的定义...
当没有任何实现细节可用于当前代码范围时,应使用接口.
当您可以使用某些实施细节时,应使用摘要.
查询 - 为什么还需要这些条款?为什么Business对象不能直接与DataAccess.SqlServer Layer通信?
我有这个Enum的扩展方法:
public static List<Enum> Values(this Enum theEnum)
{
return Enum.GetValues(theEnum.GetType()).Cast<Enum>().ToList();
}
Run Code Online (Sandbox Code Playgroud)
我收到了代码分析违规行为:
CA1062验证公共方法的参数
在外部可见方法'EnumExtensions.Values(this Enum)'中,在使用之前验证参数'theEnum'.
为什么会这样?如何验证参数?我无法检查null,因为枚举是一个不可为空的值类型.是否有其他检查应该在这里发生?
c# ×10
async-await ×4
asp.net ×2
linq ×2
wpf ×2
.net-core ×1
appdomain ×1
c#-3.0 ×1
c#-4.0 ×1
enums ×1
hottowel ×1
html ×1
ienumerable ×1
javascript ×1
nuget ×1
oop ×1
ravendb ×1
reflection ×1
unit-testing ×1
validation ×1
web ×1