有人可以解释为什么AsyncMethod2会导致死锁吗?我(认为我)理解顶级 Task inAsyncMethod1不会尝试在由 捕获的上下文中执行它的延续BlockingMethod,因此避免了死锁,但我不明白在 引擎盖下发生了什么AsyncMethod2:
private static void BlockingMethod(IEnumerable<Object> data)
{
AsyncMethod1(data).Wait(); // no deadlock
AsyncMethod2(data).Wait(); // deadlock
}
private static async Task AsyncMethod1(IEnumerable<Object> data)
{
await Task.Run(async () =>
{
foreach (var obj in data)
{
await AsyncMethod2.(obj);
}
}).ConfigureAwait(false);
}
private static async Task AsyncMethod2(IEnumerable<Object> data)
{
await Task.Run(async () =>
{
foreach (var obj in data)
{
await AsyncMethod2.(obj).ConfigureAwait(false);
}
});
}
Run Code Online (Sandbox Code Playgroud) 我在这里发布了另一个 SO 问题,作为后续,我的同事做了一个测试,如下所示,作为 async/await/Tasks 参数的某种形式的“反击”。
(我知道lock不需要 on resultList,请忽略)
new Task().Start()会在 ThreadPool 上调度操作,并在 ThreadPool 上的不同线程上执行测试代码。这是否意味着第一次和第二次测试或多或少相同?(我猜不是,请解释我有一个关于异步编程的问题:
带任务的异步代码(不带异步/等待)和带异步/等待的异步代码有什么区别?
在C#中,我们可以使用Task来编写异步代码或方法,也可以使用关键字。
带任务的异步代码(无异步/等待)
static Task DoWorkAsync()
{
var work = Task.Run(() => { Thread.Sleep(5000); });
var workcompleted = work.ContinueWith((x) => { Console.WriteLine("Work Completed!!!"); });
return work;
}
Run Code Online (Sandbox Code Playgroud)
带有 Async/Await 的异步代码
static async Task DoWorkAsync()
{
await Task.Run(() => { Thread.Sleep(10000); });
Console.WriteLine("Work Completed");
}
Run Code Online (Sandbox Code Playgroud)
如果能回答我的问题,我真的很感激。
我注意到,那HttpResponseMessage.Content是有ReadAsStringAsync()方法的。当此操作需要 cpu 并且任务反应会增加更多 CPU 工作时,使其异步有何意义?
请帮忙。
我想在从数据库中读取时使用 IsIndeterminate= true 属性查看进度条的变化。
我知道我可以使用 Task 和 BackgroundWorker 创建另一个线程。但对我来说,非常重要的是,我不会离开进行长期操作的方法,直到它完成。在这种情况下可以做什么?
PS对不起我的英语:)
我需要并行运行任务并向它们传输大约 3-5 个参数,但现在我向任务传输了 2 个参数,因此,我总是在控制台中看到值 100。
告诉我我做错了什么?以及如何正确地将参数传递给任务?
class Program
{
static void Main(string[] args)
{
/// Init
string file_name = "unknown.dat";
Action<string, int> action = (msg, count) => Load(msg, count);
/// For
for (int i = 0; i < 100; i++)
{
Task.Factory.StartNew(() => action(file_name, i));
}
/// End
Console.Read();
}
public static void Load(string aFileName, int aCount)
{
Console.WriteLine("Index: {0} ", aCount);
}
}
Run Code Online (Sandbox Code Playgroud)
我来这里是因为我使用这段代码有一个奇怪的行为:但在此之前,我知道这样做是一个非常糟糕的做法,所以它甚至没有在现实中使用我只是想了解幕后发生的事情但我对此知之甚少。
这是有问题的代码:
int worker = 0;
int io = 0;
Console.WriteLine($"Worker thread {worker} Io thread {io}");
ThreadPool.GetAvailableThreads(out worker, out io);
ThreadPool.GetMaxThreads(out var workerThreadsMax, out var completionPortThreadsMax);
Console.WriteLine($"Worker thread {workerThreadsMax - worker} Io thread {completionPortThreadsMax - io}");
for (int i = 0; i < 100; i++)
{
Task.Run(() =>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " - Running thread");
ThreadPool.GetAvailableThreads(out var worker2, out var io2);
ThreadPool.GetMaxThreads(out var workerThreadsMax2, out var completionPortThreadsMax2);
Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId} - Worker thread {workerThreadsMax2 - worker2} Io thread {completionPortThreadsMax2 - io2}");
var …Run Code Online (Sandbox Code Playgroud) 我在使用异步方法时遇到一些问题。我对它有点陌生,但我正在编写一些 Blazor 代码并使用 Blob 存储,并且一些调用需要异步。这是我的代码和问题。此代码需要异步,因为它从 Azure 获取 Blob 数据。(FileUpload 是我的自定义对象):
public async Task<List<FileUpload>> GetAllFilesAsync()
{
// TODO: GENERATE fileupload objects here and return
await foreach (var blobItem in _container.GetBlobsAsync())
{
var name = blobItem.Name;
BlobClient blobClient = _container.GetBlobClient(name);
FileUpload fileUploadViewModel = new FileUpload()
{
FileName = blobItem.Name,
FileStorageUrl = blobClient.Uri.ToString(),
ContentType = blobItem.Properties.ContentType,
};
_allFiles.Add(fileUploadViewModel);
}
return _allFiles;
}
Run Code Online (Sandbox Code Playgroud)
在我的 Blazor 代码(服务器)中,我有以下代码在初始化时调用服务:
private List<FileUpload> fileUploadViewModels = new();
protected override async Task OnInitializedAsync()
{
GetAllBlobsAsync();
}
private void GetAllBlobsAsync()
{
var …Run Code Online (Sandbox Code Playgroud) 我目前在使用抛出异常的方法时遇到了一些问题,但我不确定原因.该异常使我的应用程序崩溃.
System.NullReferenceException: Object reference not set to an instance of an object.
at Myapp.AutoProcess.<ToRead>d__36.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__1(Object state)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
Run Code Online (Sandbox Code Playgroud)
我在一个单独的线程上运行该方法
Thread listenerThread = new Thread(() => ToRead());
listenerThread.Start();
Run Code Online (Sandbox Code Playgroud)
抛出异常的方法如下所示:
private async void ToRead()
{
while (true)
{
if (this.toRead.Count != 0)
{ …Run Code Online (Sandbox Code Playgroud) 我运行几个任务并将它们保存在列表中以检查它们是否已经完成.
我发现来自async方法RanToCompletion的任务总是显示为任务本身仍在运行.
Task在两种情况下,有没有办法从对象获取"完整"信息?
这是一个显示此行为的简单测试用例.我运行两个任务,有/没有async方法,并在完成期间和完成后检查状态.
private void test()
{
;
Action actionAsync = funcAsync;
Task taskAsync = Task.Run(actionAsync);
Action action = func;
Task task = Task.Run(action);
var statusAsync = taskAsync.Status;
var status = task.Status;
// stati are either WaitingToRun or Running
Thread.Sleep(TimeSpan.FromSeconds(2));
// Now it's quite certain, that both have started
var statusAsync2 = taskAsync.Status;
var status2 = task.Status;
Debug.Assert(statusAsync2 == TaskStatus.RanToCompletion);
Debug.Assert(status2 == TaskStatus.Running);
;
Thread.Sleep(TimeSpan.FromSeconds(12));
// Now it's quite certain, that both …Run Code Online (Sandbox Code Playgroud) c# ×10
task ×10
async-await ×6
.net ×5
asynchronous ×2
asp.net ×1
httpclient ×1
progress-bar ×1
wpf ×1