我需要优化WCF服务......这是一件非常复杂的事情.这次我的问题与任务有关(Task Parallel Library,.NET 4.0).发生的事情是我在调用服务(使用Task.Factory.StartNew
)时启动了几个任务,然后等待它们完成:
Task.WaitAll(task1, task2, task3, task4, task5, task6);
Run Code Online (Sandbox Code Playgroud)
好吧......我看到,不喜欢的是,在第一次通话时(有时前2-3次通话,如果一个接一个地快速完成),最后的任务比其他任务开始得晚(我正在寻找)在其他人开始后0.5秒开始的情况下).我试着打电话
ThreadPool.SetMinThreads(12*Environment.ProcessorCount, 20);
Run Code Online (Sandbox Code Playgroud)
在我的服务开始,但它似乎没有帮助.
这些任务都与数据库相关:我正在从多个数据库中读取数据,并且必须花费尽可能少的时间.
知道为什么最后一项任务花了这么长时间吗?有什么我可以做的吗?
或者,我应该直接使用线程池吗?事实上,在我看到的一个案例中,一个任务在最后一个任务开始之前已经结束 - 如果我重新使用该线程而不是等待创建新线程,我将节省0.2秒.但是,我不能肯定该任务将最后总是这么快,所以我不能把两个请求在相同的任务.
[编辑]操作系统是Windows Server 2003,因此不应该有连接限制.此外,它托管在IIS中 - 我不知道我是应该创建常规线程还是使用线程池 - 这是首选版本?
[编辑]我也尝试过使用Task.Factory.StartNew(action, TaskCreationOptions.LongRunning);
- 它没有帮助,最后一项任务仍然比其他任务开始的时间晚了很多(大约半秒钟后).
[编辑] MSDN 1说:
在启动新的空闲线程之前,线程池具有内置延迟(.NET Framework 2.0版中的半秒).如果您的应用程序在短时间内定期启动许多任务,则空闲线程数量的少量增加可以显着提高吞吐量.将空闲线程数设置得太高会不必要地消耗系统资源.
但是,正如我所说的,我已经在调用SetMinThreads并且它没有帮助.
我正在尝试在同一网络上的SQL Express实例,与我的域用户进行身份验证.它可以在SSMS中使用Windows身份验证.我确认我可以使用MyDB数据库,包括编辑表格.
但是,当我尝试以下连接字符串时:
Server=ipaddress\SQLExpress; Database=MyDB; Integrated Security=SSPI;
我收到了一个错误:
Cannot open database "MyDB" requested by the login. The login failed.
Login failed for user 'ROMANIA\MONSTER2$'
问题是MONSTER2是我的计算机的名称,而不是我的用户名.(ROMANIA是域名.)我做错了什么?
[编辑]我忘记了可能相关的内容:我正在尝试从计算机上运行的Web服务打开连接.
我在调用工作流方法时使用此代码检索远程IP地址:
private static string GetRemoteIP()
{
var oc = OperationContext.Current;
var mp = oc.IncomingMessageProperties;
var remp = mp[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
return remp == null ? "(unknown)" : remp.Address;
}
Run Code Online (Sandbox Code Playgroud)
但是,我得到的地址是":: 1".我不想要IPv6地址,我想要IPv4(127.0.0.1) - 任何强制这种方式?
更多WCF问题...... :)
我的所有工作流程都实现了相同的3种方法.经过大量的复制和粘贴后,我决定让它们从相同的界面继承:
[ServiceContract(Namespace = "http://schema.company.com/messages/")]
public interface IBasicContract<TRequest, TResponse>
where TRequest : class
where TResponse : class
{
[OperationContract(Name = "GetReport",
Action = "http://schema.company.com/messages/GetReport",
ReplyAction = "http://schema.company.com/messages/GetReportResponse")]
TResponse GetReport(TRequest inquiry);
[OperationContract(Name = "GetRawReport",
Action = "http://schema.company.com/messages/GetRawReport",
ReplyAction = "http://schema.company.com/messages/GetRawReportResponse")]
string GetRawReport(string guid);
[OperationContract(Name = "GetArchiveReport",
Action = "http://schema.company.com/messages/GetArchiveReport",
ReplyAction = "http://schema.company.com/messages/GetArchiveReportResponse")]
TResponse GetArchiveReport(string guid);
}
Run Code Online (Sandbox Code Playgroud)
我还决定创建服务客户端的通用实现:
public class BasicSvcClient<TRequest, TResponse> : ClientBase<IBasicContract<TRequest, TResponse>>, IBasicContract<TRequest, TResponse>
where TRequest : class
where TResponse : class
{
public BasicSvcClient()
{
}
public …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Moq 3.x,它运行得非常好.但是,我有一个问题,我无法弄清楚如何解决.特定
public interface ITestSpec
{
bool Run(Action<string, string> onIncorrectResponse);
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试以下方法:
var passingTestSpec = new Mock<ITestSpec>();
passingTestSpec
.Setup(m => m.Run(null))
.Returns(true);
Action<string, string> fakeAction =
(expected, actual) => { throw new Exception("Should not run"); };
Assert.IsTrue(passingTestSpec.Object.Run(fakeAction));
Run Code Online (Sandbox Code Playgroud)
我的问题是对passTestSpec.Object.Run(......某些动作......)的任何调用都返回false.似乎Moq库试图将操作与我在Setup()调用中传递给Run()的参数匹配,并且失败.实际上我在Run()调用中放了什么动作并不重要......它仍然返回false.
有任何想法吗?
[编辑]我刚刚发现了一些东西; 如果我用安装线替换
.Setup(m => m.Run(fakeAction))
Run Code Online (Sandbox Code Playgroud)
测试通过.但是,我不知道将调用.Run()方法的操作,因此这不是一个解决方案.有谁知道It.IsAny等同于行动?
我需要从IIS中托管的wcf服务内部进行多次异步调用(可能是相关的,我不知道).这些调用是针对其他服务的,但我通过将字符串POST到服务URL来创建它们.同步调用它们有效,但我有十几个调用,它们完全独立,所以我想通过异步调用它们来加速它们.
现在,我意识到我可以简单地使用多个线程 - 这可能是最简单的解决方案 - 但我想我会尝试异步.
我的代码与此类似:
public delegate void Callback(string response);
public static void InvokeAsync(string request, string url, Callback callback)
where TResponse: class
{
var web = new WebClient();
web.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
web.UploadStringCompleted += (sender, e) => callback.Invoke(e.Result);
web.UploadStringAsync(new Uri(url), request);
}
//...
var lockObj = new object();
foreach (var item in list)
InvokeAsync(item, url, response => { lock(lockObj) newList.Add(response); });
Run Code Online (Sandbox Code Playgroud)
我相信上述应该有效; 但是,我的问题是我不知道如何等待所有的回复.如果我使用计数器并在循环中等待它变为零,则不会有任何CPU来处理回调.与使用某种形式的信号量相同,我相信.是否有一种无阻塞的方式等待我收回所有回复?(更改方法签名以进行回调只会将问题提升一级,我担心.)
[编辑]这是一个非常接近的问题 - 如何调用异步操作作为同步?- 但我需要等待多个异步操作.
我试图想出一个linq查询来转换IEnumerable<int>
为另一个IEnumerable<int>
,其中结果中的每个int是从初始列表到该位置的所有int的总和:
鉴于int[] a
我需要int[] b
Where b[0] = a[0], b[1] = a[0] + a[1], b[2] = a[0] + a[1] + a[2]
等等
或者,上面的总和可以写成b[1] = b[0] + a[1], b[2] = b[1] + a[2]
等等,但我不知道这会有什么帮助.
当然,我可以通过for
循环执行此操作,但是我从查询中获取a []序列,并且我认为如果我继续查询而不是突然添加for
那里它会更好看:)
我有以下场景:
IObservable<E>
E
以获得E1
错误状态,在这种情况下我需要错误消息M1
E1
以获得E2
错误消息M2
还有一个额外的复杂性,因为结果 En 和/或错误消息Mn
可能取决于所有值E
, E1
, ..., En-1
- 而不仅仅是En-1
。
考虑到所有这些,是否有比我正在使用的更好的模式?
[编辑] 根据要求,我添加了一个完整的工作示例;不幸的是,这使得这篇文章变得相当大。
internal class Program
{
private static void Main()
{
var stream = Enumerable.Range(1, 10).Select(i => new Record { Id = i }).ToObservable();
stream
.Select(it => new ComplexType { Item = it })
.SelectIfOk(Process1)
.SelectIfOk(Process2)
.SelectIfOk(ProcessN)
.Subscribe(DisplayResult);
Console.ReadLine();
}
private static ComplexType Process1(ComplexType data)
{ …
Run Code Online (Sandbox Code Playgroud) 我正在尝试学习ASP.NET MVC,我遇到了这个问题:我有一个"查看产品详细信息"表单,我想将其重新用作添加/编辑表单.(当您查看产品详细信息时,如果您有权执行此操作,则应显示"编辑"链接;它应重新显示相同的表单,但此时启用了文本框字段.)
现在,Details视图看起来像这样:
<% var product = ViewData.Model; %>
<table>
<tr>
<td>Name</td>
</tr>
<tr>
<td><%= Html.TextBox("Name", product.Name, new { size = "50", disabled = "disabled"})%></td>
</tr>
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以重用它而不在视图中放置太多逻辑?例如,我需要删除disabled = "disabled"
部件(但size
部件需要留在那里),将所有内容放在表单中等等.
如果不能这样做,那很好,我只是想多次重复同样的事情,以防我需要改变它(我会).
我有以下型号:
public class Product
{
[Key]
[HiddenInput(DisplayValue = false)]
public int Id { get; set; }
[Required]
[StringLength(10)]
public string ProductCode { get; set; }
[Required]
[StringLength(40)]
public string ProductName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
以及控制器中的以下一对Add方法:
[HttpGet]
public ActionResult Add()
{
return View();
}
[HttpPost]
[ValidateInput(false)]
[ValidateAntiForgeryToken]
public ActionResult Add(Product product)
{
productRepository.Add(product);
return RedirectToAction("Index");
}
Run Code Online (Sandbox Code Playgroud)
这是添加视图:
@using Models
@model Product
<h2>Add Product</h2>
@using (@Html.BeginForm("Add", "Home")) {
@Html.AntiForgeryToken()
@Html.EditorForModel()
<input type="submit" id="btnSubmit" value="Submit"/>
}
Run Code Online (Sandbox Code Playgroud)
一切都显示得很好,不幸的是我无法提交表格.我花了一段时间才弄清楚Id字段是否经过验证.实际上,如果我删除该HiddenInput
属性,我可以看到提交它告诉我需要Id字段.
有没有办法在仍然使用时将其标记为不需要EditorForModel()
?
我有以下 LINQ 代码:
return from policy in db.Policy.Include(it => it.LedgerLines)
let balance = policy.LedgerLines.Sum(it => it.Amount)
where balance > 0m && balance < 5m
select policy;
Run Code Online (Sandbox Code Playgroud)
这被翻译成
return from policy in db.Policy.Include(it => it.LedgerLines)
let balance = policy.LedgerLines.Sum(it => it.Amount)
where balance > 0m && balance < 5m
select policy;
Run Code Online (Sandbox Code Playgroud)
有没有办法只执行SUM([p1].[Amount])
一次子查询?
(EF 核心 3.1)
我的ExcelReader
C#应用程序中有一个类 - 我需要将Excel电子表格导入数据库表.我的问题是,这是为数不多的未经测试的类之一 - 我不能使用"模拟输入",并且使用实际的Excel电子表格进行测试会使测试有点慢(大约一秒钟).我知道班级工作正常 - 我手动测试了 - 但我有点不安,没有自己的测试就离开它.
所以 - 我的问题是:哪一个更好:没有单元测试,慢单元测试,或者第三种方法我无法弄清楚?
[编辑]很多很棒的答案,我真的很抱歉,我只能标记一个.
c# ×11
linq ×2
wcf ×2
.net ×1
asp.net-mvc ×1
asynchronous ×1
generics ×1
moq ×1
sql ×1
tcp ×1
tdd ×1
unit-testing ×1
webclient ×1