C# 中执行 Task.Run(async () =>)调用同一个方法只执行一次
时间: 2024-04-22 16:27:27 浏览: 11
执行 `Task.Run(async () =>)` 时,传入的是一个异步函数,该函数会在一个新的线程中执行。如果该异步函数中调用了同一个方法,确实会出现只执行一次的情况,这是因为该方法可能会被锁定,直到前一个线程执行完毕后才能被下一个线程执行。
为了避免这种情况,可以使用 `SemaphoreSlim` 类实现方法的异步锁定。在方法的开头使用 `await semaphore.WaitAsync()` 方法获取锁,在方法的结尾使用 `semaphore.Release()` 方法释放锁。这样就可以确保同一时间只能有一个线程执行该方法,避免出现只执行一次的情况。
相关问题
C#中List<Task> taskList = new List<Task>(); taskList.Add(Task.Run(async () => { try { _log.LogInformation($"Start to update Thumbnail data, ID: {activityModel.Id}"); await ProcessThumbnail(activityModel.Thumbnail, activity, user); //throw new Exception(); } catch (Exception ex) { _log.LogError("An error: Upload Thumbnail is Invalid."); throw new Exception(); } })); taskList.Add(Task.Run(async () => { try { _log.LogInformation($"Start to add Attachments data, ID: {activityModel.Id}"); await ProcessAttachments(activityModel, activity, user); } catch (Exception ex) { _log.LogError("An error: Upload Attachment is Invalid."); throw new Exception(); } })); Task.WaitAll(taskList.ToArray());里面的task只执行了一个是什么原因
在这段代码中,`Task.Run` 方法会创建一个新的线程,并在该线程中执行传入的异步函数。`List<Task>` 中包含两个 `Task`,分别对应两个异步函数,即 `ProcessThumbnail` 和 `ProcessAttachments`。
在调用 `Task.WaitAll(taskList.ToArray())` 方法时,程序会等待所有的 `Task` 执行完毕后再继续往下执行。如果其中任意一个 `Task` 抛出了异常,整个程序会崩溃。
如果只有一个 `Task` 执行了,有可能是因为其中一个 `Task` 出现了异常,导致该 `Task` 执行失败,程序终止了。你可以通过在 `catch` 块中记录异常信息或者使用调试工具来确认是否有异常抛出。另外,你还可以在调用 `Task.WaitAll(taskList.ToArray())` 方法前,输出一些日志信息来确认程序的执行情况。
C# 定时调用同一cmd进程 执行standardinput.writenlineAsync 如果前一次命令未完成,则跳过
你可以使用 `Process` 类来执行 cmd 命令,并且使用 `StandardInput` 属性来写入命令。要实现你所需的功能,你可以将 `Process` 对象和一个标志变量一起存储在类的成员变量中,如下所示:
```csharp
public class CommandRunner
{
private Process _process;
private bool _isRunning = false;
public async Task RunCommand(string command)
{
if (_isRunning)
{
Console.WriteLine("Previous command is still running, skipping...");
return;
}
_process = new Process();
_process.StartInfo.FileName = "cmd.exe";
_process.StartInfo.Arguments = "/c " + command;
_process.StartInfo.UseShellExecute = false;
_process.StartInfo.RedirectStandardInput = true;
_process.StartInfo.RedirectStandardOutput = true;
_isRunning = true;
_process.Start();
await _process.StandardInput.WriteLineAsync(command);
// Wait for the command to complete
await _process.WaitForExitAsync();
_isRunning = false;
}
}
```
在 `RunCommand` 方法中,我们首先检查是否有上一个命令正在运行,如果是,则跳过。否则,我们创建一个新的 `Process` 对象并执行 cmd 命令。我们使用 `_isRunning` 标志变量来跟踪是否有命令正在运行,并在命令完成后将其设置为 `false`。请注意,我们使用 `await` 关键字来等待命令完成。此外,我们在 `ProcessStartInfo` 中设置了 `RedirectStandardInput` 属性,以便能够向 cmd 进程中写入命令。
你可以像这样使用 `CommandRunner` 类来运行命令:
```csharp
var runner = new CommandRunner();
await runner.RunCommand("dir");
await runner.RunCommand("ping google.com");
```
在这个示例中,我们创建了一个新的 `CommandRunner` 实例,并使用它来运行两个命令:`dir` 和 `ping google.com`。如果第一个命令还没有完成,则第二个命令将被跳过。