2017-12-22 167 views
6

Tôi phải gửi 10000 tin nhắn. Tại thời điểm này, nó xảy ra đồng bộ và mất đến 20 phút để gửi tất cả.Gửi 5000 tin nhắn theo cách không đồng bộ trong C#

// sending messages in a sync way 
foreach (var message in messages) 
{ 
    var result = Send(message); 
    _logger.Info($"Successfully sent {message.Title}.") 
} 

Để rút ngắn thời gian gửi tin nhắn, tôi muốn sử dụng không đồng bộ và chờ đợi, nhưng lo ngại của tôi là thời gian chạy C# có thể xử lý 15000 nhiệm vụ trong quy trình công nhân.

var tasks = new List<Task>(); 
foreach (var message in messages) 
{ 
    tasks.Add(Task.Run(() => Send(message)) 
} 

var t = Task.WhenAll(tasks); 
t.Wait(); 
... 

Ngoài ra, về mặt trí nhớ, tôi không chắc chắn nếu đó là một ý tưởng tốt để tạo ra một danh sách 15000 nhiệm vụ

+4

TPL sử dụng một nhóm luồng và sẽ không sinh ra một luồng mới cho mỗi 'Task.Run()'. – Loris156

+3

Chỉ cần chạy điều này và xem nó như thế nào – Evk

+3

Nó sẽ chỉ rút ngắn thời gian nếu phương thức gửi có thể hoạt động song song. –

Trả lời

6

Kể từ khi tôi đi làm về, tôi đã chơi với điều này một chút và đây là câu trả lời của tôi

Đầu tiên, tất cả Parallel.ForEach đều cực kỳ thú vị khi sử dụng và với 8 lõi của tôi chạy rất nhanh.

Tôi đề nghị hạn chế sử dụng CPU để bạn không sử dụng 100% dung lượng, nhưng điều đó phụ thuộc vào hệ thống của bạn, tôi đã thực hiện hai gợi ý cho nó.

Những thứ khác là bạn cần theo dõi và đảm bảo rằng máy chủ người gửi của bạn có thể ăn tất cả các công việc này mà không gặp sự cố.

Đây là một việc thực hiện:

public void MessMessageSender(List<Message> messages) 
{ 
    try 
    { 
     var parallelOptions = new ParallelOptions(); 
     _cancelToken = new CancellationTokenSource(); 
     parallelOptions.CancellationToken = _cancelToken.Token; 
     var maxProc = System.Environment.ProcessorCount; 
     // this option use around 75% core capacity 
     parallelOptions.MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling(maxProc * 1.75)); 
     // the following option use all cores expect 1 
     //parallelOptions.MaxDegreeOfParallelism = (maxProc * 2) - 1; 
     try 
     { 
      Parallel.ForEach(messages, parallelOptions, message => 
      { 
       try 
       { 
        Send(message); 
        //_logger.Info($"Successfully sent {text.Title}."); 
       } 
       catch (Exception ex) 
       { 
        //_logger.Error($"Something went wrong {ex}."); 
       } 
      }); 
     } 
     catch (OperationCanceledException e) 
     { 
      //User has cancelled this request. 
     } 
    } 
    finally 
    { 
     //What ever dispose of clients; 
    } 
} 

câu trả lời của tôi được lấy cảm hứng cho page này.

Các vấn đề liên quan