Запрет запуска рабочего потока в родительском потокеC#

Место общения программистов C#
Ответить
Anonymous
 Запрет запуска рабочего потока в родительском потоке

Сообщение Anonymous »

Я работаю на C# и заметил, что мои потоки работают не так, как я ожидал. Во-первых, я создал BlockingCollection с собственным потоком для распечатки сообщений консоли, поскольку знаю, что печать может значительно снизить производительность и испортить результаты.
public static readonly BlockingCollection DebugMessages = new BlockingCollection();

public Form1()
{
Thread debugThread = new Thread(() =>
{
foreach(string msg in DebugMessages.GetConsumingEnumerable())
{
Console.WriteLine(msg);
}
});
debugThread.IsBackground = true;
debugThread.Priority = ThreadPriority.BelowNormal;
debugThread.Start();

Затем у меня есть еще один поток, также созданный путем создания нового потока, который выполняет дополнительную работу над другой BlockkingCollection, которая должна постоянно иметь объекты для обработки. После анализа каждого объекта я запускаю следующий код, чтобы просмотреть текущее время. Мы можем назвать эту тему «Тема Б».
long currentTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
double diff = currentTime - time;
Form1.DebugMessages.Add($"TimeDiff:{diff} Message received: "); // + e.Message
time = currentTime;

Затем внутри этого потока я иногда запускаю следующий код, идея которого состоит в том, чтобы запустить и забыть с точки зрения потока B. Я назову этот рабочий поток потоком C. Идея здесь такая: для всего в потоке C, который использует оператор await для блокировки потока C, но никогда не блокирует поток B.
Task.Run(async () =>
{
await BuyTokenAsync();
});

Мои отметки TimeDiff постоянно отключаются каждый раз, когда я вызываю метод, который использует await внутри BuyTokenAsync, так что кажется, что он блокирует поток B. Вот пример некоторых отладочных сообщений, которые были напечатаны из отдельного потока.
TimeDiff:0 Message received:
TimeDiff:0 Message received:
TimeDiff:0 Message received:
ATA created transaction sent:
TimeDiff:58 Message received:
TimeDiff:0 Message received:
TimeDiff:0 Message received:
TimeDiff:0 Message received:
TimeDiff:0 Message received:
TimeDiff:1 Message received:
TimeDiff:0 Message received:
TimeDiff:0 Message received:
TimeDiff:0 Message received:
TimeDiff:1 Message received:
TimeDiff:0 Message received:
Buy transaction sent:
TimeDiff:317 Message received:
TimeDiff:0 Message received:
TimeDiff:0 Message received:
TimeDiff:0 Message received:
TimeDiff:1 Message received:

Теперь код, соответствующий отправленной транзакции, созданной ATA и находящейся в BuyTokenAsync, будет следующим.
Form1.DebugMessages.Add($"ATA created transaction sent:");
var ataSendResponse = await rpcClient.SendTransactionAsync(ataTransaction.Serialize(), skipPreflight: true);
if (!ataSendResponse.WasSuccessful)
{
Form1.DebugMessages.Add($"Failed to send ATA creation transaction Reason:{ataSendResponse.Reason} Result:{ataSendResponse.Result} Error:{ataSendResponse.ServerErrorCode}");
throw new Exception($"Failed to send ATA creation transaction Reason:{ataSendResponse.Reason}");
}

Во-вторых, код, соответствующий отправленной транзакции покупки: отладочное сообщение, которое также находится в BuyTokenAsync и также должно выполняться в потоке C.
Form1.DebugMessages.Add($"Buy transaction sent:");

// Confirm the buy transaction
var confirmResponse = await rpcClient.GetTransactionAsync(sendResponse.Result, Commitment.Confirmed);
if (!confirmResponse.WasSuccessful)
{
Form1.DebugMessages.Add($"Failed to confirm buy transaction. Reason{confirmResponse.Reason} Result:{confirmResponse.Result} Error:{confirmResponse.ServerErrorCode}");
throw new Exception($"Failed to confirm buy transaction. Reason{confirmResponse.Reason} Result:{confirmResponse.Result} Error:{confirmResponse.ServerErrorCode}");
}


Исходя из того, что это происходит каждый раз для общедоступного асинхронного метода Task BuyTokenAsync(), я знаю, что он должен каким-то образом блокировать либо поток B, либо, возможно, поток BlockingCollection, который печатает? Хотя я не уверен, почему и как это возможно. Также обратите внимание, что в моем коде не используются блокировки или что-то подобное. Я даже пытался изменить Task.Run на следующий, но та же проблема все еще сохраняется. Что я делаю не так?
Task.Factory.StartNew(async () =>
{ // Fully isoloate the following thread from its parent thread above
try
{
Form1.DebugMessages.Add("Buying");
await BuyTokenAsync().ConfigureAwait(false);
}
catch (Exception ex)
{
Form1.DebugMessages.Add($"Error in BuyTokenAsync: {ex.Message}");
}
}, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);**


Подробнее здесь: https://stackoverflow.com/questions/792 ... ent-thread
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»