我正在开发一个调用外部服务的应用程序,并且必须将外部集合的所有条目添加到本地集合中.目前的问题是外部集合可能超过1000条记录,但返回的搜索结果最多只能包含20个项目.
为了速度,我认为使用一组任务将是前进的方向,所以我想出了下面的代码:
int totalCount = returnedCol.total_count;
while (totalCount > myDict.Count)
{
int numberOfTasks = // logic to calculate how many tasks to run
List<Task> taskList = new List<Task>();
for (int i = 1; i <= numberOfTasks; i++)
{
Interlocked.Add(ref pageNumber, pageSize);
Task<SearchResponse> testTask = Task.Run(() =>
{
return ExternalCall.GetData(pageNumber, pageSize);
});
Thread.Sleep(100);
taskList.Add(testTask);
testTask.ContinueWith(o =>
{
foreach (ExternalDataRecord dataiwant in testTask.Result.dataiwant)
{
if (!myDict.ContainsKey(dataiwant.id))
myDict.GetOrAdd(dataiwant.id, dataiwant);
}
});
}
Task.WaitAll(taskList.ToArray());
}
Run Code Online (Sandbox Code Playgroud)
但是,这不会产生所有结果.该pageNumber
变量正确每次递增,但似乎不是所有的任务结果正在分析(如在上一个较小的数据的单个线程相同的逻辑设置返回所有预期的结果).此外,我尝试在链(而不是循环)中声明单个任务,并且全部返回测试数据.似乎我传入的值Thread.Sleep()
越高,结果被添加到本地集合中越多(但这并不理想,因为这意味着该过程需要更长时间!)
目前在600个记录的样本中,我只有大约150-200个添加到该myDict
集合中.我错过了一些明显的东西吗
我们目前正在研究日志记录解决方案,并实现了一个名为“Log”的扩展方法。写入日志文件时,理想情况下,我们希望写入原始变量名(而不是扩展方法中使用的变量名)。
为此,我们目前要做的是:
public void DoSomeWork()
{
String testString = "Hey look I'm a string!";
testString.Log("testString value");
}
Run Code Online (Sandbox Code Playgroud)
使用扩展方法:
public static String Log(this String valueToStore, String name)
{
// The logging code which uses the 'name' parameter
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是,在较长的代码行上阅读变得困难并且看起来很聚集。理想的情况是这样的:
public void DoSomeWork()
{
String testString = "Hey look I'm a string!";
testString.Log();
}
Run Code Online (Sandbox Code Playgroud)
使用扩展方法:
public static String Log(this String valueToStore)
{
// The logging code which is able to retrieve the
// value 'testString' from the 'valueToStore' value
}
Run Code Online (Sandbox Code Playgroud)
通过使用反射,这完全可能吗?我知道这个nameof …
背景:我正在编写一个应用程序,它遍历服务器列表并获取有关每台机器的各种详细信息.在迭代期间,我需要更新表单上的各种控件(以显示所获取信息的摘要).因为它正在遍历列表,所以我调用了Thread.Sleep()以允许用户有时间在查询下一台机器之前读取信息.以下是我的代码:
Task TestTask = Task.Factory.StartNew(() =>
{
foreach (String IpAddress in ServersToCheck)
{
if (IpAddress != String.Empty)
{
ServerBeingCheckedLabel.Text = IpAddress;
if (PingServer(IpAddress) == true)
{
PingChar_Label.ForeColor = Color.Green;
PingChar_Label.Text = "a";
CheckPermissionsAreValid(IpAddress);
}
else
{
PingChar_Label.ForeColor = Color.Red;
PingChar_Label.Text = "r";
PermChar_Label.ForeColor = Color.Red;
PermChar_Label.Text = "r";
}
}
}
Thread.Sleep(10000);
this.BackColor = FormBackGroundColor;
TestButton.Enabled = true;
RunTimer.Enabled = true;
}, CancellationToken.None, TaskCreationOptions.None, UiScheduler);
Run Code Online (Sandbox Code Playgroud)
这在更新窗体上的控件时工作正常,但在Thread.Sleep()期间,UI会锁定.当然,如果在单独的任务上调用Thread.Sleep(),UI线程仍然未被阻塞?
我继承了以下扩展方法,该方法基于文件路径创建ImageSource对象
public static class ImageSourceExtensions
{
[StructLayout(LayoutKind.Sequential)]
public struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
public const uint SHGFI_ICON = 0x100;
public const uint SHGFI_LARGEICON = 0x0;
[DllImport("shell32.dll")]
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
public static ImageSource GetIconFromFolder(this string filePath)
{
SHFILEINFO shinfo = new SHFILEINFO();
SHGetFileInfo(filePath, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), …
Run Code Online (Sandbox Code Playgroud)