Modeless WPF Behavior understanding with await & async

Modeless WPF Behavior understanding with await & async

ahmed.elhawary73
Advocate Advocate
519 Views
6 Replies
Message 1 of 7

Modeless WPF Behavior understanding with await & async

ahmed.elhawary73
Advocate
Advocate

Hello dears,

 

I'm Creating a Revit Add-in, In the code Below I'm trying to download some files from the Internet using await & async  to hold my code till downloading files is complete then continue the code-(I replaced my code with await Task.Delay(5000); for simplification) , the problem is as follow:

  • The Code is not waiting for the download to finish and it directly gives the user "Download Finished2" messege.
  • The Code Not Running "Download Finished1" even if the method I call implemented successfully and I'm pretty sure that all files downloaded correctly.
  • IF I replaced my method with Thread.Sleep(5000); all the code run very well without any issue.

 

 private async Task Btn_Click()
        {
            TaskDialog.Show("RES", "Download Will Start now");
            if (IU.CheckConnection())
            {
                await revitTask.Run(async (uiapp) =>
                {
               #Thread.Sleep(5000);
                  await  Task.Delay(5000);
                    TaskDialog.Show("RES", "Download Finished1");
                });
            }
            TaskDialog.Show("RES", "Download Finished2");
        }

 

 

 

0 Likes
520 Views
6 Replies
Replies (6)
Message 2 of 7

jeremy_tammik
Alumni
Alumni

TaskDialog is a Revit API call. It requires a valid Revit API context. Such a context is only provided in the main thread of a Revit event handler. As soon as you start using async and await, you are leaving this main thread, and you no longer have access to the Revit API context, so you cannot make calls to the Revit API. If you wish to implement any kind of interaction at all with the Revit API from a modeless context, your one and only option is to implement an external event, as demonstrated by the official Revit SDK sample ModelessDialog / ModelessForm_ExternalEvent and discussed by The Building Coder in the topic group on Idling and External Events for Modeless Access and Driving Revit from Outside:

  

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 7

ricaun
Advisor
Advisor

You cannot add the 'async' inside the 'revitTask.Run'. 

 

Revit API code can only execute synchronously, you should remove the 'async' and use the 'Thread.Sleep(5000)'.

 

 

 

Luiz Henrique Cassettari

ricaun.com - Revit API Developer

AppLoader EasyConduit WireInConduit ConduitMaterial CircuitName ElectricalUtils

0 Likes
Message 4 of 7

ahmed.elhawary73
Advocate
Advocate

Hello @ricaun ,

I'm thrilled you are answering my question, as I said in the Above Topic await Task.Delay(5000) It's just a simulation for my downloading files method so I want to wait till downloading files finish, then continue the code can I do this or not applicable using Revit API Context! 

 

0 Likes
Message 5 of 7

jeremy_tammik
Alumni
Alumni

You can set up an external event that is triggered when the process that you are waiting for completes.

    

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 6 of 7

Chuong.Ho
Advocate
Advocate

I remember I used one to run a process in Revit Design Automation with Download the data from bucket and then execute the update data, I'm using this way with help from @ricaun and it working well, I'm belive it working with your case too, the important here is you can't add code execute relate to revit api inside execute :

 

var task = Task.Run(async () =>
{
    await Task.Delay(1000);
    return "Task message";
});
var message = task.GetAwaiter().GetResult();

 

I also have a post detail here and I hope it can help : https://dev.to/chuongmep/use-await-async-revit-api-3nk4

Chuong Ho

EESignature

0 Likes
Message 7 of 7

ahmed.elhawary73
Advocate
Advocate

Dear Jeremy, please till give me a small example, I've tried to implement the below code but my application freezes:

 

 

private async void Btn_CLIK(object sender, System.Windows.Input.MouseEventArgs e)
        {
         

                
                await IU.FamilyDownload(Fambtn.FamilyDownloadPath, Fambtn.FamilyName, Fambtn.FamilyCloudDirec);
                Fambtn.BorderBrush = Downloadedfamilycolour;
                

            
                    ExtHand.Request = My_Requests.Load_Family;
                    ExtEvent.Raise();
                               
                    }

 

0 Likes