Warum ist Task.run () hier erforderlich?C#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Warum ist Task.run () hier erforderlich?

Post by Anonymous »

Ich schreibe eine API, die Daten nach der Rückgabe einer Antwort an den Benutzer verarbeitet und etwas hat, das sich wie die folgenden verhält. < /p>

Code: Select all

var processor = new Processor();
await processor.DoSomeWork();

public class Worker
{
public ConcurrentDictionary Tasks { get; set; } = new();
}

public class Processor
{
private readonly Worker _worker;

public Processor()
{
_worker = new();
}

public async Task DoSomeWork()
{
for (int i = 0; i < 10; i++)
DoSomething();
}

int DoSomething()
{
Console.WriteLine(nameof(DoSomething));
return DoSomethingElse();
}

int DoSomethingElse()
{
Console.WriteLine(nameof(DoSomethingElse));

// Waits for DoAnotherThing to be complete
_worker.Tasks.TryAdd(Guid.NewGuid().ToString(), DoAnotherThing());

// Returns back to DoSomething immediately
_worker.Tasks.TryAdd(Guid.NewGuid().ToString(), Task.Run(DoAnotherThing));
return 1;
}

async Task DoAnotherThing()
{
Console.WriteLine(nameof(DoAnotherThing));

// Uncommenting this line returns back to calling method without blocking
// await Task.Delay(1000);

// Running this line by itself blocks the app and doesn't return to caller until DoAnotherThingHere is complete
// unless the method DoAnotherThing() is called with Task.Run()
await DoAnotherThingHere();

return 1;
}

// Implementation does not matter here
async Task DoAnotherThingHere()
{
Console.WriteLine(nameof(DoAnotherThingHere));
await Task.Delay(5000);
return 5;
}
}
Warum ist Task.run () Erforderlich Für meine Doanotherthing -Methode, die nicht blockiert, wenn ich zu einem gleichzeitigen Dokument addiere. Task.run () und ein Warten auf Task.delay () Vor der aufrufenden asynchrieenden Methode kehren Sie sofort zum Anrufer zurück und verarbeitet anschließend das Doanotherthhere Methode im Hintergrund. haben. < /p>
Was fehlt mir hier?

Code: Select all

private async Task StreamResultsToS3Async(StreamResultsToS3Params streamingParams) where T : class
{
try
{
await foreach (var item in StreamAsync(streamingParams.Streamable, searchSpec, batchProcessingSize, exportLog))
{
_exportService.ProcessingQueue.Enqueue(uploadNumber);

var thresholdReached = _exportService.FileSizeThresholdReached(exportRequest, multiPartUploadRequest.FileSize);

var uploadId = multiPartUploadRequest.UploadId;
if (!uploadId.HasValue())
{
Interlocked.Increment(ref fileNumber);
uploadId = await _exportService.InitiateMultiPartUploadAsync(exportRequest, multiPartUploadRequest, fileNumber, exportLog.ClientId);
}

multiPartUploadRequest = ProcessDataAndTryGetNextUploadRequestAsync(streamingParams,
thresholdReached, uploadId, exportLog, item, exportRequest, uploadNumber, fileNumber,
multiPartUploadRequest);

Interlocked.Increment(ref uploadNumber);
}
}
catch (Exception ex)
{
Log.Error(ex, "Unexpected error occurred when exporting data.  Error: {Error} StackTrace: {StackTrace}", ex.Message, ex.StackTrace);
}
}

private InternalAmazonS3MultiPartUploadRequest ProcessDataAndTryGetNextUploadRequestAsync(StreamResultsToS3Params streamingParams,
bool thresholdReached, string uploadId, ExportLog exportLog, (bool IsComplete, DataResult Result) item,
MultiPartUploadExport exportRequest, int uploadNumber, int fileNumber,
InternalAmazonS3MultiPartUploadRequest multiPartUploadRequest) where T : class
{
if (!_exportService.ProcessingTasks.ContainsKey(uploadId))
_exportService.ProcessingTasks.TryAdd(uploadId, new ConcurrentBag());

// This is the line that blocks / waits for completion unless I add a task with Task.Run
_exportService.ProcessingTasks[uploadId].Add(ProcessDataResultImplAsync(streamingParams, exportLog, item.Result, exportRequest,
multiPartUploadRequest, fileNumber, uploadNumber, uploadId, thresholdReached, item.IsComplete));

return !thresholdReached ? multiPartUploadRequest : new InternalAmazonS3MultiPartUploadRequest(_exportService.GetFilename(exportRequest.Identifier, exportRequest.ExportFileType, ++currentFileNumber));
}

private async Task ProcessDataResultImplAsync(StreamResultsToS3Params streamParams, ExportLog exportLog, DataResult item,
MultiPartUploadExport exportRequest, InternalAmazonS3MultiPartUploadRequest uploadRequest, int fileNumber, int partNumber, string uploadId, bool fileSizeThresholdReached, bool isFinished) where T : class
{
exportLog.ProcessDataStopwatch.Start();

// adding this line immediately returns to StreamResultsToS3Async
// await Task.Delay(1000);

// Without await Task.Delay, it waits for this method to complete before returning to the calling method ProcessDataAndTryGetNextUploadRequestAsync
var searchResponse = await ProcessEntityDataAsync(item);

exportLog.ProcessDataStopwatch.Stop();

_exportService.ProcessMultiPartUploadAsync(exportRequest, uploadRequest, searchResponse, exportLog, fileNumber, partNumber, uploadId, fileSizeThresholdReached, isFinished).SafeFireAndForget();
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post