这是我试图模拟的代码。我可以删除 async-await 来执行“即发即忘”,但我试图理解异步(非阻塞)代码的目的,但看起来 AWAIT 是运行该方法之前的阻塞代码NextProcess()。如果我删除等待,它就满足了我的目标,但是在后台运行完成后有没有办法获得任何类型的异常或状态?
public static async Task Main()
{
Console.WriteLine("Starting the long-running process...");
await Task.Run(() => LongRunningProcess());
NextProcess();
}
private static void LongRunningProcess()
{
// Simulating the work being done
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
Thread.Sleep(1000);
}
}
private static void NextProcess()
{
Console.WriteLine("In See method, continuation without waiting!");
}
Run Code Online (Sandbox Code Playgroud)
我尝试了粘贴代码的各种排列。
我有一个文件(~30MB),我用 File.ReadAllBytes() 读取该文件,该文件有很多不同长度的结构化数据(中间没有终止符)。所以我必须检查第一个数据的长度,将其剪掉并继续下一个数据,依此类推。因此,将其拆分为不同的任务是不可能的。
还有其他方法可以加快这个速度吗?(目前大约需要20分钟)
List<Record> Records = new List<Record>
internal static void Import(List<byte> filedata)
{
var task = Task.Run(() =>
{
while (filedata.Count > 0)
{
Record record = new Record()
filedata = record.GetData(filedata);
Records.Add(record)
}
});
}
//inside class "Record"
internal List<byte> GetData(List<byte> filedata)
{
this.length = BitConverter.ToUInt32(new byte[4] { filedata[8], filedata[9], filedata[10], filedata[11] }, 0);
this.data = new byte[this.length + 1];
filedata.CopyTo(0, this.data, 0, this.length);
filedata.RemoveRange(0, 16 + this.length);
return filedata;
}
Run Code Online (Sandbox Code Playgroud) 我在这里遇到了一个问题,你可能知道答案:我只是仍然无法弄清楚。
我在这里为一个简单的场景创建一个种子:为给定的帖子添加“喜欢”。方法签名是:
async Task GeneratePostLike(string postId, string userId, CancellationToken cancellationToken = default) {
return await postLikeService.AddUserLikeToPost(
new PostLikeInput { PostId = postId, UserId = userId },
cancellationToken
);
}
Run Code Online (Sandbox Code Playgroud)
我想随机生成对帖子的点赞。我正在使用随机和其他机制来获取随机数来执行此操作。
当我使用旧的 for 循环块时,它会按照我想要的方式执行。这是我正在使用的说明:
var numberOfLikesForPost = random.Next(1, 100);
var randomUsersForLikes = await userService.GetRandomUsers(numberOfLikesForPost);
for (var likeIndex = 0; likeIndex < numberOfLikesForPost; likeIndex++)
{
var randomUserId = randomUsersForLikes.PickRandom().Id;
await GeneratePostLike(post.Id!, randomUserId, cancellationToken);
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用 时Task.WhenAll,它只是执行一两次迭代并继续。看起来它的行为就像某种“一劳永逸”的行为。以下代码代表了我对Task.WhenAll块所做的事情:
var numberOfLikesForPost = random.Next(1, 100);
var randomUsersForLikes = await userService.GetRandomUsers(numberOfLikesForPost);
var generatePostLikeTasks …Run Code Online (Sandbox Code Playgroud) 我使用C#已经有10多年了,但今天我发现Dictionary<string, int>保留了插入顺序?据我所知,Dictionary内部是使用哈希表实现的,所以内部排列应该没有特定的顺序,但是下面的测试代码似乎显示遍历时的顺序和插入的顺序是一模一样的?
const int N = 1000000;
List<string> ss = new List<string>();
Dictionary<string, int> dict = new Dictionary<string, int>();
for (int i = 0; i < N; ++i)
{
var s = string.Empty;
for (int j = 0; j < 15; ++j)
s += (char)('a' + UnityEngine.Random.Range(0, 26));
//ss.add(s);
ss.Add(new string(s));
//dict[s] = UnityEngine.Random.Range(0, 1024);
dict.Add(s, UnityEngine.Random.Range(0, 1024));
}
int same = 0;
var keys = dict.Keys.ToArray();
for (int i = 0; i < N; ++i) …Run Code Online (Sandbox Code Playgroud) 我有一段看起来很简单的代码,但似乎并非如此。
// Enum values
IEnumerable values = Enum.GetValues(typeof(TVal)).Cast<TVal>();
// Sort them by alpha
if (sortByAlpha)
{
values = (values).OrderBy(i => i.ToString());
}
Run Code Online (Sandbox Code Playgroud)
如果我写:
// Get enum values
IEnumerable values = Enum.GetValues(typeof(TVal)).Cast<TVal>();
// Sort them by alpha
if (sortByAlpha)
{
values = Enum.GetValues(typeof(TVal)).Cast<TVal>().OrderBy(i => i.ToString());
}
Run Code Online (Sandbox Code Playgroud)
有用。
为什么?第一段代码中的值应该相同吗?我没有看到什么?在 .Net 4.5.1 上运行
LIST FOR 00:00:00.0000980
LIST FOREACH 00:00:00.0000007
ARRAY FOR 00:00:00.0028450
ARRAY FOREACH 00:00:00.0051233
Run Code Online (Sandbox Code Playgroud)
我一直用数组来制作性能较重的东西,但列表似乎要快得多。
using System;
using System.Diagnostics;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var cron = NCrontab.Advanced.CrontabSchedule.Parse("0 0 1 1 * 2016",
NCrontab.Advanced.Enumerations.CronStringFormat.WithYears);
var date = new System.DateTime(year: 2016, month: 1, day: 1,
hour: 0, minute: 0, second: 0);
int[] testArray = new int[1000000];
List<int> testList = new List<int>(1000000);
var stopWatch = new Stopwatch();
stopWatch.Start();
for (int i = 0; i < testList.Count;i++)
{
var …Run Code Online (Sandbox Code Playgroud) 我有几个txt文件,每个文件包含超过300万行。每行包含客户的连接,其中有客户 ID、IP 地址......
我需要找到特定的 IP 地址并获取与其相关的客户 ID。
我读取该文件并将其拆分为一个数组,并通过 foreach 在每一行中进行搜索,但由于有很多行,因此出现以下错误。
引发了“System.OutOfMemoryException”类型的异常。
我应该解压缩 txt 文件,因为它们是压缩的。我使用下面的代码:
string decompressTxt = decompressTxt = this.Decompress(new FileInfo(filePath));
char[] delRow = { '\n' };
string[] rows = decompressTxt.Split(delRow);
for (int i = 0; i < rows.Length; i++){
if(rows[i].Contains(ip)){
}
}
string Decompress(FileInfo fileToDecompress)
{
string newFileName = "";
string newFIleText = "";
using (FileStream originalFileStream =fileToDecompress.OpenRead())
{
string currentFileName = fileToDecompress.FullName;
newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length);
using (FileStream decompressedFileStream = File.Create(newFileName))
{
using (GZipStream decompressionStream = new …Run Code Online (Sandbox Code Playgroud) 我在一个文件夹中有一堆文本文件,它们都应该有相同的标题。换句话说,所有文件的前 100 行应该是相同的。所以我写了一个函数来检查这个条件:
private static bool CheckHeaders(string folderPath, int headersCount)
{
var enumerators = Directory.EnumerateFiles(folderPath)
.Select(f => File.ReadLines(f).GetEnumerator())
.ToArray();
//using (enumerators)
//{
for (int i = 0; i < headersCount; i++)
{
foreach (var e in enumerators)
{
if (!e.MoveNext()) return false;
}
var values = enumerators.Select(e => e.Current);
if (values.Distinct().Count() > 1) return false;
}
return true;
//}
}
Run Code Online (Sandbox Code Playgroud)
我使用枚举器的原因是内存效率。我没有在内存中加载所有文件内容,而是逐行同时枚举文件,直到发现不匹配,或者检查了所有标题。
注释的代码行很明显我的问题。我想利用一个using块来安全地处理所有枚举器,但不幸的using (enumerators)是不能编译。显然using只能处理一个一次性物品。我知道我可以通过将整个事物包装在一个try-finally块中并最终在内部循环中运行处理逻辑来手动处理枚举器,但这似乎很尴尬。using在这种情况下,是否有任何机制可以使该语句成为可行的选择?
更新
我刚刚意识到我的函数有一个严重的缺陷。枚举器的构造并不稳健。锁定的文件可能会导致异常,而某些枚举器已被创建。这些枚举器不会被处理。这是我想要解决的问题。我在想这样的事情:
var enumerators = Directory.EnumerateFiles(folderPath)
.ToDisposables(f …Run Code Online (Sandbox Code Playgroud) 我有一个关于创建一个可以等待的计时器的想法,而不是引发事件。我还没有想到任何实际应用,可能不是非常有用的东西,但我想看看它是否至少可以作为练习。这是它的用法:
var timer = new System.Timers.Timer();
timer.Interval = 100;
timer.Enabled = true;
for (int i = 0; i < 10; i++)
{
var signalTime = await timer;
Console.WriteLine($"Awaited {i}, SignalTime: {signalTime:HH:mm:ss.fff}");
}
Run Code Online (Sandbox Code Playgroud)
计时器等待 10 次,预期输出为:
等待 0,信号时间:06:08:51.674
等待 1,信号时间:06:08:51.783
等待 2,信号时间:06:08:51.891
等待 3,信号时间:06:08:52.002
等待 4,信号时间:05:108:
等待 5、信号时间:06:08:52.218
等待 6、信号时间:06:08:52.332
等待 7、信号时间:06:08:52.438
等待 8、信号时间:06:08:52.546
等待 06:52.332 信号时间:06:08:52.0608:
在这种情况下,一个简单的await Task.Delay(100)会做同样的事情,但计时器提供了从程序的另一部分控制间隔的灵活性(注意可能的线程安全问题)。
关于实现,我找到了一篇文章,描述了如何使各种事物成为可等待的,例如 a TimeSpan、 an int、 aDateTimeOffset和 a Process。似乎我必须编写一个返回 a 的扩展方法TaskAwaiter …
我像这样链接我的异步任务,
await MyTask_1().ContinueWith(async x=>
{
// do other stuff
await MyTask_2().ContinueWith(async y =>
{
await MyTask_3().ContinueWith(async z =>
{
// and more tasks
});
});
});
Run Code Online (Sandbox Code Playgroud)
我想在上一个任务完成后运行一个任务,所以我只找到了链接它们的方法。
但是还有其他不那么丑陋、更干净或更短的方法来实现这一目标吗?
using System;
using System.Linq;
namespace Problem
{
class Prog
{
public static void Main(string[] args)
{
long t= long.Parse(Console.ReadLine());
while (t-->0)
{
long n, even = 0, odd = 0, a;
n = long.Parse(Console.ReadLine());
for (long i = 0; i < n; i++)
{
a = long.Parse(Console.ReadLine());
if (a % 2)
odd++;
else
even++;
}
Console.WriteLine((even < odd) ? even : odd);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
由于我是 C# 新手,因此我正在使用此代码来解决hackerearth 中的问题,因此正在练习,但实际上我没有得到如何解决此错误的说法:
solution.cs(21,25):错误 CS0029:无法将类型“long”隐式转换为“bool”
编译失败:1 个错误,0 个警告`
各位开发者大家好,
我对条件语句中两种不同方法的效率有疑问。我试图确定以下两种情况之间哪个选项更快:
1.使用逻辑运算符&&将两个条件组合在一个if语句中:if (条件1 && 条件2)
2.利用嵌套的if语句分别评估条件:
if (condition1) {
if (condition2) {
// Code block executed if both conditions are true
}
}
Run Code Online (Sandbox Code Playgroud)
我的目标是优化我的代码并确保我在执行时间方面使用最有效的方法。因此,我非常感谢您对这两种替代方案的性能影响的见解。
具体来说,我有兴趣了解计算开销、短路评估行为和整体执行速度方面的任何潜在差异。
如果您对这个主题有任何经验或知识,或者您可以向我指出相关资源,我将不胜感激您的帮助。先感谢您!
到目前为止我收集到的信息是,哈希码是整数,有助于更快地从数组中查找数据。看这段代码:
string x = "Run the program to find this string's hash code!";
int hashCode = x.GetHashCode();
Random random = new Random(hashCode);
for(int i = 0; i<100; i++)
{
// Always generates the same set of random integers 60, 23, 67, 80, 89, 44, 44 and so on...
int randomNumber = random.Next(0, 100);
Console.WriteLine("Hash Code is: {0}", hashCode);
Console.WriteLine("The random number it generates is: {0}", randomNumber);
Console.ReadKey();
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我使用字符串的哈希码x作为随机数生成器的种子。这段代码给了我 100 个随机整数,但每次运行该程序时,它都会给我相同的随机数集!我的问题是:为什么每次循环迭代时它都会给我一个不同的随机数?为什么 x 的哈希码不断变化,即使字符串没有改变。哈希码到底是什么以及它们是如何生成的(如果需要)?
c# ×13
.net ×6
async-await ×4
performance ×3
linq ×2
list ×2
arrays ×1
asynchronous ×1
byte ×1
dictionary ×1
dispose ×1
enumeration ×1
hash ×1
hashcode ×1
ienumerable ×1
preserve ×1
random ×1
task ×1
timer ×1