Quantcast
Channel: ADO.NET, Entity Framework, LINQ to SQL, NHibernate
Viewing all articles
Browse latest Browse all 1698

Getting deadlock with Task async/await

$
0
0

First off, I'm a total newbie when it comes to Web APIs. This is actually my first attempt. I'm beginner-intermediate when it comes to Winforms.

That being said, I've created a Web API (ASP.NET Web Application) that basically interfaces with a SQL server to retrieve entries in a certain database. I've also created a simple Winform application that uses the API to get that information from the database. I come from a procedural background, so my OO-approach might be a little messy. Originally, my Winform app was written moreprodecurally, and everything worked fine, i.e. I could call the API from the UI (Form1.cs) and I would get back the correct data.

However, once I began abstracting out, and creating a more OO-environment, I had to implement a lot of Tasks, asyncs, awaits, etc. When I step through my code, the correct data is returned; however, it locks the UI. 

In my Form1.cs, I have the following:

string selected = radioButtonArray.FirstOrDefault(c => c.Checked).Name;
BusinessLogicLayer BLL = new BusinessLogicLayer(serialNumbersToPrint);
BLL.Process(selected);

This takes the name of the radiobutton that is checked and passes it into the BussinessLogicLayer.cs class. The "serialNumbersToPrint" is just a list of objects that would get populated once the code is successfully executed.

Going to my Business Logic Layer, I have the following: 

 public class BusinessLogicLayer
    {
        private List<AbstractDatabaseContents> localCollection;

        public BusinessLogicLayer(List<AbstractDatabaseContents> ObjectList)
        {
                localCollection = ObjectList;
        }

        public void Process(string deviceType)
        {
            DeviceType dT = new DeviceType(localCollection);

            Strategy strategy = dT.deviceType(deviceType).Result;
            var context = new StrategyContext(strategy);
            context.ContextInterface();
        }
    }

Pretty straightforward, I think. Here's the DeviceType class:

public class DeviceType
    {
        private List<AbstractDatabaseContents> localCollection;
        private Strategy sd;
        public string lastSerial { get; set; }

        public DeviceType(List<AbstractDatabaseContents> ObjectList)
        {
            localCollection = ObjectList;
        }

        public async Task<Strategy> deviceType(string deviceType)
        {
            sd = null;

            if (deviceType == "radioCamOldUS")
            {
                Object lS = await SqlAPI.GetSerialAsync("CAMOLD");
                lastSerial = lS.ToString();
                int dType = 1;
                sd = new Cam(lastSerial, dType, localCollection);
            }
            return sd;
        }

    }

And finally, my SqlAPI class:

public class SqlAPI
    {     
        public static async Task<object> GetSerialAsync(string path)
        {
            using (var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }))
            {
                Object sn = null;
                client.BaseAddress = new Uri("https://localhost:44319/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                HttpResponseMessage response = await client.GetAsync($"api/DeviceData?deviceType={path}").ConfigureAwait(false);

                if (response.IsSuccessStatusCode)
                {
                    sn = await response.Content.ReadAsAsync<object>();
                }

                return sn;
            }
        }
    }

The above code is all in my WinForm application. The first few lines in the Web API Controller in the web application is:

public class DeviceDataController : ApiController
    {
        public DeviceDataController()
        {
            using (ManufacturingEntities entities = new ManufacturingEntities())
            {
                entities.Configuration.ProxyCreationEnabled = false;
            }
        }

        public List<string> sn = new List<string>();
        public List<string> sn2 = new List<string>();
        public List<int> intList = new List<int>();
        public List<int> intList2 = new List<int>();
        public async Task<object> Get(string deviceType)
        {
            using (ManufacturingEntities entities = new ManufacturingEntities())
            {
                List<Device_Devices> CAM = entities.Device_Devices.Where(c => c.DeviceTypeID == 1).
                    Where(c => SqlFunctions.IsNumeric(c.SerialNumber) > 0).
                    Where(c => String.Compare(c.SerialNumber, "100000") > 0 &&
                        String.Compare(c.SerialNumber, "999999") <= 0).
                        ToList(); 
                sn = CAM.Select(o => o.SerialNumber).ToList();
                foreach (var item in sn)
                {
                    int i = Convert.ToInt32(item);
                    intList.Add(i);
                }

                if (deviceType == "CAMNEW")
                {
                    List<int> Result = new List<int>(intList.FindAll(c => c > 100000 && c < 999999));
                    Result.Sort();
                    int first = Result[0];
                    return Result[Result.Count - 1];
                }
                if (deviceType == "CAMOLD")
                {
                    List<int> Result = new List<int>(intList.FindAll(c => c > 0 && c < 99999));
                    Result.Sort();
                    int first = Result[0];
                    return Result[Result.Count - 1];
                }
            }
        }
    }

Again, the problem is deadlock. It works when I, e.g., put a button on the UI of the WinForm, and then program the click event like:

        private async void metroButton1_Click(object sender, EventArgs e)
        {
            Object lS = await SqlAPI.GetSerialAsync("CAMOLD");
            string lastSerial = lS.ToString();
            txtStatus.AppendText(lastSerial);
        }

I'm not entirely sure why it's deadlocking like this. I've read a few articles about why things deadlock, but in this particular case, I couldn't find the reason why.


Viewing all articles
Browse latest Browse all 1698

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>