C#多线程与异步/等待结合 [英] C# multithreading combined with async/await

查看:120
本文介绍了C#多线程与异步/等待结合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是与C#中的多线程有关的另一个问题.

This is yet another question related to multi-threading in C#.

但是,将多线程与async/await结合使用似乎很有趣.

However, when multi-threading combined with async/await seems to be interesting.

我有一个生成线程的方法,该线程异步调用对象的方法.

I have a method generating threads which invoke methods of objects asynchronously.

但是,上下文不是由不同类的对象共享的.

However, the context is not shared by objects of different classes.

例如,考虑代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ThreadDataSharing
{
    class Data
    {
        public static ThreadLocal<string> Name = new ThreadLocal<string>();
    }

    class Locker { public static object lobj = new object { };}
    class Program2
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 3; i++)
            {
                var pObj = new Program();
                new Thread(new ThreadStart(pObj.MyThreadMethod)).Start();
            }
        }
    }
    class Program
    {

        ///my async method
        ///
        public async Task MyAsyncMethod()
        {
            lock (Locker.lobj)
            {
                Console.WriteLine("From async method");
                Console.WriteLine("thread: " + Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine("id: " + Data.Name.Value);
            }

            await MyAsyncMethod2();

            await new AsyncClass().AsyncMethod();
        }

        public async Task MyAsyncMethod2()
        {
            lock (Locker.lobj)
            {
                Console.WriteLine("From async 2 method");
                Console.WriteLine("thread: " + Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine("id: " + Data.Name.Value);
            }

            await Task.Run(() =>
            {
                lock (Locker.lobj)
                {
                    Console.WriteLine("From task run method");
                    Console.WriteLine("thread: " + Thread.CurrentThread.ManagedThreadId);
                    Console.WriteLine("id: " + Data.Name.Value);
                }
            });
        }

        public void MyThreadMethod()
        {
            lock (Locker.lobj)
            {
                Console.WriteLine("From thread method");
                Console.WriteLine("thread: " + Thread.CurrentThread.ManagedThreadId);

                var id = Guid.NewGuid();
                Data.Name.Value = id.ToString();
                Console.WriteLine("id: " + Data.Name.Value);
            }

            MyAsyncMethod().Wait();
        }
    }


    public class AsyncClass
    {
        public async Task AsyncMethod()
        {
            lock (Locker.lobj)
            {
                Console.WriteLine("From class async method");
                Console.WriteLine("thread: " + Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine("id: " + Data.Name.Value);
            }

            var newId = Guid.NewGuid();
            Data.Name.Value = newId.ToString();

            await AsyncMethod2();
        }

        public async Task AsyncMethod2()
        {
            lock (Locker.lobj)
            {
                Console.WriteLine("From class async 2 method");
                Console.WriteLine("thread: " + Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine("id: " + Data.Name.Value);
            }

            await Task.Run(() => { });
        }
    }

}

运行此代码会在我的机器上产生以下输出

Running this code produces the following output on my machine

From thread method
thread: 3
id: 3a7ef8e3-ebe1-49e1-94bb-798358ac1567
From thread method
thread: 4
id: 341d3371-f905-4e1c-aac3-47bda16c8d88
From thread method
thread: 5
id: b7e79901-81b7-430f-b158-59f091e43a0c
From async method
thread: 3
id: 3a7ef8e3-ebe1-49e1-94bb-798358ac1567
From async method
thread: 5
id: b7e79901-81b7-430f-b158-59f091e43a0c
From async method
thread: 4
id: 341d3371-f905-4e1c-aac3-47bda16c8d88
From async 2 method
thread: 3
id: 3a7ef8e3-ebe1-49e1-94bb-798358ac1567
From async 2 method
thread: 4
id: 341d3371-f905-4e1c-aac3-47bda16c8d88
From async 2 method
thread: 5
id: b7e79901-81b7-430f-b158-59f091e43a0c
From task run method
thread: 6
id:
From task run method
thread: 8
id:
From task run method
thread: 7
id:
From class async method
thread: 7
id:
From class async method
thread: 6
id:
From class async method
thread: 8
id:
From class async 2 method
thread: 8
id: f52ed654-0e55-4906-bfc1-65c6b25a7785
From class async 2 method
thread: 7
id: 1e53e03b-a3a0-4296-8622-7716b45d1462
From class async 2 method
thread: 6
id: 1adca81d-b11a-4860-b37d-a017afe877b8

问题是,为什么它不与第二个类( AsyncClass )的实例共享 ThreadLocal< T> 对象?

Question is, why is it not sharing the ThreadLocal<T> object with the instance of the second Class (AsyncClass)?

推荐答案

在具有await/async的控制台应用程序中,没有共享的同步上下文,这可能就是为什么它不共享的原因.

In a Console app with await/async there isn't shared synchronization context, may be this is the reason why it's not shared.

这篇关于C#多线程与异步/等待结合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆